moduleNameMapper has no effect using Jest in Angular CLI - jestjs

I'm trying to use Jest with angular cli.
I have the following in my tsconfig:
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"importHelpers": true,
"outDir": "./dist/out-tsc",
"sourceMap": true,
"module": "es2020",
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noUnusedLocals": true,
"noImplicitThis": true,
"allowSyntheticDefaultImports": true,
"target": "es2015",
"typeRoots": ["node_modules/#types"],
"lib": ["es2017", "es2018.promise", "dom"],
"paths": {
"#src/*": ["src/*"],
"#app/*": ["src/app/*"],
"#core/*": ["src/app/#core/*"],
"#shared/*": ["src/app/#shared/*"],
}
},
"angularCompilerOptions": {
"fullTemplateTypeCheck": true,
"strictInjectionParameters": true,
"strictTemplates": true
}
}
And the following in my jest.config.js:
module.exports = {
preset: 'ts-jest',
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
testPathIgnorePatterns: ['/node_modules/', '/dist/', 'src/app/*.{js}'],
collectCoverage: true,
coverageDirectory: 'jest-coverage',
moduleNameMapper:{
'^#src/(.*)$': '<rootDir>/src/$1',
'^#app/(.*)$': '<rootDir>/src/app/$1',
'^#core/(.*)$': '<rootDir>/src/app/#core/$1',
'^#shared/(.*)$': '<rootDir>/src/app/#shared/$1',
},
};
ng serve and ng build work correctly. Just ng test doesn't compile with: Cannot find module for every import statement using a path from paths.
Can anyone tell why this isn't working?

I'm sure you've probably come right since posting this, but the following works for me - I suspect that the pattern matching may have interfered :(
I do also just use the jest-preset-angular config instead.
module.exports = {
preset: "jest-preset-angular",
globalSetup: "jest-preset-angular/global-setup",
moduleNameMapper: {
"#app/(.*)": "<rootDir>/src/app/$1",
"#env": "<rootDir>/src/environments/environment",
"#test/(.*)": "<rootDir>/src/test/$1",
},
roots: ["<rootDir>/src"],
};

Related

TS-JEST Mongoose/MongoDB incompatibility with ESM

I am trying to get Node Express/Typescript app that uses Mongoose (which drags in Mongodb) to work with Jest. I know what the error is, I just can't find the correct configuration to get jest and mongodb to play nicely.
No matter what I try I either get:
chart-review-server2.0/node_modules/mongodb/src/bson.ts:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import type {
^^^^^^
SyntaxError: Cannot use import statement outside a module
or if I try to exclude it from the config using transformIgnorePatterns in my jest.config.js configuration like this: transformIgnorePatterns: ['node_modules/(?!(mongodb))'], I get:
RangeError: Maximum call stack size exceeded
at Object.get [as ObjectId] (node_modules/mongodb/src/bson.ts:38:3)
at Object.get [as ObjectId] (node_modules/mongodb/src/bson.ts:38:3)...
My jest.config.js file looks like this:
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
transformIgnorePatterns: [`node_modules/(?!(mongodb))`],
transform: {
'^.+\\.ts?$': 'ts-jest'
},
moduleDirectories: [ "node_modules", "src", "test"],
verbose: true,
testMatch: ["<rootDir>/test/*(*.)+(test).+(ts)"],
setupFiles: [
'dotenv/config'
],
};
my tsconfig.json looks like this:
{
"compilerOptions": {
"lib": [
"es6"
],
"module": "commonjs",
"target": "es5",
"rootDirs": [
"./src"
],
"outDir": "./dist",
"baseUrl": "./src",
"moduleResolution": "node",
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"allowJs": true,
"downlevelIteration": true,
"isolatedModules": false,
"noEmit": true
},
"include": [
"src/**/*.ts",
"test/**/*.ts"
],
"exclude": [
"node_modules"
],
"types": [
"node"
],
"typeRoots": [
"node_modules/#types"
]
}
Thanks in advance for any replies, and for reading this.
Commenting out moduleDirectories on jest.config.js solved the issue for me. All credits to #jimmythecode, see his answer.

How to use tsconfig-paths with ts-node

How do you setup paths with typescript to run with ts-node? And later compile paths to absolute paths when compiling?
I have following very minimal structure:
koki.ts:
export const calculate = (a: number, b: number) => {
return a + b;
};
index.ts:
import { calculate } from "#koki/koki";
const result = calculate(1, 2);
console.log(result);
tsconfig.json:
{
"ts-node": {
"transpileOnly": true,
"require": ["tsconfig-paths/register"]
},
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"lib": ["dom", "es6", "es2017", "esnext.asynciterable"],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"#/*": ["*"],
"#koki/*": ["koki/*"]
}
},
"exclude": ["node_modules"],
"include": ["./src/**/*.ts"]
}
I am getting:
ts-node src/index.ts
Error: Cannot find module '#koki/koki'
Require stack:
- /home/pwnage/Documents/github/test-node/src/index.ts
In my case, I added the -r option to ts-node scripts
package.json
"scripts": {
"start": "ts-node -r tsconfig-paths/register src/index.ts",
}
ts-node works well in these codes
import { env } from "#/config/env";

How solve experimentalDecorators warning using typescript and PM2?

I'm working on a project that uses node.js with typescript. If I run TSC or a command to build the project, it works because I have the option "experimentalDecorators": true in my tsconfig.json.
But when I put it into my dev server using pm2 with the same configuration, doesn't work using the exosystem.config.json and without.
First, I have this tsconfig.json:
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"lib": ["dom", "es6", "es2017", "esnext.asynciterable"],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"rootDir": "src",
"composite": true,
"declaration": true,
"noEmitOnError": false,
"preserveConstEnums": true,
},
"exclude": ["node_modules"],
"include": ["src"],
}
My project structure is:
index.ts
tsconfig.json
src/
ecosystem.config.js
My ecosystem.config.js is:
module.exports = {
apps : [{
name: "app",
script: './index.ts',
autorestart: true,
exec_mode: "fork",
watch: true,
env: {
NODE_ENV: 'development',
},
env_production: {
NODE_ENV: 'production',
},
}
],
};
And if I debug the pm2 logs I have this error:
Error
I solve this error with this ecosystem.config.js configuration:
module.exports = {
apps : [{
name: 'app',
script: './node_modules/.bin/ts-node',
args: '-P ./tsconfig.json ./index.ts',
watch: true,
restart_delay: 10000,
wait_ready: true
}],
};

serverless framework not recognizing tsconfig's paths

I'm trying to deploy my Node.js app to Lambda using Serverless framework, however, my Node code uses paths from tsconfig.json for referencing imports but the Serverless deploy process fails. How do you wire up serverless.yml to acknowledge and use paths defined in tsconfig.json?
I've installed serverless-plugin-typescript, but it does not seem to recognize paths from tsconfig.
serverless.yml
service:
name: app-name
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
plugins:
- serverless-webpack
- serverless-plugin-typescript
...
tsconfig.ts
{
"compileOnSave": true,
"compilerOptions": {
"lib": [
"es2017"
],
"baseUrl": "./src",
"declaration": true,
"downlevelIteration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"module": "commonjs",
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
"outDir": "./dist",
"paths": {
"#config/*": [
"config/*"
],
"#core/*": [
"core/*"
],
"#infra/*": [
"infra/*"
],
"#modules/*": [
"modules/*"
],
"#shared/*": [
"shared/*"
]
},
"preserveConstEnums": true,
"removeComments": true,
"rootDir": "./src",
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictNullChecks": false,
"target": "es2017",
"typeRoots": [
"node_modules/#types"
],
"types": [
"node"
]
},
"include": [
"./**/*.ts"
],
"exclude": [
"node_modules/**/*",
".serverless/**/*",
".webpack/**/*",
"_warmup/**/*",
".vscode/**/*"
]
}
I found an answer. Turns out you need to install tsconfig-paths-webpack-plugin. Then in webpack.config.js you add the following:
npm install --save-dev tsconfig-paths-webpack-plugin
inside webpack.config.js:
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
...
resolve: {
plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })]
},
...
};
NOTE: be sure to use the plugins inside the resolve section. There is a plugins a the root, however, TsconfigPathsPlugin only works in resolve/plugins.
I hope this helps you if you experience this same issue.

can't transform a folder inside node_modules with ts-jest

I'm writing tests in typescript, and i've got private dependencies in node_modules/#my-modules folder. I'm using ts-jest compiler and jest still complains about esnext modules in node_modules folder.
package versions:
"#types/jest": "^23.3.12",
"jest": "^23.6.0",
"ts-jest": "^23.10.5",
tsconfig.json:
{
"compilerOptions": {
"baseUrl": "./src",
"outDir": "build/dist",
"module": "commonjs",
"target": "es5",
"lib": ["es5", "es6", "dom", "esnext"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": false,
"strict": false,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
}
}
jest.config.js:
module.exports = {
globals: {
"ts-jest": {
diagnostics: true,
tsConfig: "<rootDir>/tsconfig.json",
},
},
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
preset: "ts-jest",
roots: ["<rootDir>/src/"],
setupTestFrameworkScriptFile: "<rootDir>/src/setupEnzyme.ts",
snapshotSerializers: ["enzyme-to-json/serializer"],
testEnvironment: "jest-environment-jsdom",
transformIgnorePatterns: [
"node_modules/(?!(#my-modules)/)",
]
};
exact error when running jest:
Details:
/sites/frontend/node_modules/#my-modules/ui-components/.dist/src/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export { default as Calendar } from './components/calendar';
^^^^^^
SyntaxError: Unexpected token export
What is the proper way to transpile files in #my-modules for jest?
The config that works for me right now
package versions:
"#types/jest": "^24.0.17",
"jest": "^24.8.0",
"ts-jest": "^23.10.5",
tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "build/dist",
"lib": ["es5", "es6", "dom", "esnext"],
"module": "esnext",
"moduleResolution": "node",
"target": "es5",
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"rootDir": "src",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
},
"exclude": [
"node_modules",
"build",
"dist"
]
}
jest.config.js:
module.exports = {
globals: {
"ts-jest": {
diagnostics: true,
tsConfig: "<rootDir>/tsconfig.json",
},
},
moduleDirectories: [
"node_modules",
"utils",
__dirname,
],
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
moduleNameMapper: {
"\\.(css|less)$": "identity-obj-proxy",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
"<rootDir>/config/jest/fileMock.js",
},
preset: "ts-jest",
roots: ["<rootDir>/src/"],
setupFilesAfterEnv: ["<rootDir>/config/jest/setupJest.ts"],
snapshotSerializers: ["enzyme-to-json/serializer"],
testEnvironment: "jest-environment-jsdom",
transform: {
"^.+\\.jsx?$": "babel-jest",
"^.+\\.tsx?$": "ts-jest",
},
transformIgnorePatterns: [
"node_modules/(?!(#my-modules)/)",
],
};
config/jest/fileMock.js:
module.exports = 'test-file-stub';
I followed the tuto here and worked like a charm
npm install --save-dev jest typescript ts-jest #types/jest
npx ts-jest config:init
Another solution for me was to update the jest.config.ts so it contains the following setting
transform: {
//"^.+\\.(ts|tsx)$": "ts-jest",
},

Resources