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

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",
},

Related

ts-node: require() of ES modules is not supported

I have a node app written in TypeScript that compiles with tsc and then runs with node ./dist/index.js with no problem. However, I would like to use nodemon to watch the source and so have been playing with ts-node.
I have run into and solved a few issues, but the issue I have now is a problem using the threads.js library:
require() of ES modules is not supported.
As I say, tsc produces the working target no problem, so why might it be falling over with this?
I am currently just trying ts-node --esm ./src/index.ts. I have also tried this in my tsconfig.json:
"ts-node": { "esm": true, "experimentalSpecifierResolution": "node" },
Here is my tsconfig.json:
{
"ts-node": { "esm": true, "experimentalSpecifierResolution": "node" },
"compilerOptions": {
"target": "es2020",
"lib": [
"es2015",
"es2016",
"es2020",
"esnext",
"dom"
],
"module": "es2020",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"noImplicitAny": false
},
"include": [
"src/**/*.ts",
"typings.d.ts"
]
}
Clues?

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 fix Typescript ReferenceError Class not defined when importing class as type

I'm using the typescript with the eslint rule #typescript-eslint/consistent-type-imports which requires me to import types as types (import type { InputType }...).
However when I do that with an exported es6 class, say Car, (import type { Car } from './models') I get the error:
ReferenceError: Car is not defined
Car is a class exported from car.model.ts as follows:
export class Car {
...
}
Please how do I fix this?
I use the following packages:
"#typescript-eslint/eslint-plugin": "^4.31.0",
"#typescript-eslint/parser": "^4.31.0",
"ts-node-dev": "^1.1.8",
"typescript": "^4.4.2"
My ./tsconfig.json is as follows:
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "es2019",
"allowJs": true,
"strict": false,
"noImplicitAny": false,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "build",
"baseUrl": ".",
"typeRoots": [
"./src/types/*",
"./node_modules/#types"
],
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"include": [
"src/**/*"
]
}
My nodejs version
"node": "^12.13.1"

moduleNameMapper has no effect using Jest in Angular CLI

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"],
};

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.

Resources