javascript - 在 jest 中运行测试时,node_modules 导入变为 undefined
我的 Jest 配置有什么问题,以至于我无法在 Jest 执行中解析 node_modules?它们得到的是 undefined...
示例测试文件:
import lodash from 'lodash'
it('test', () => {
expect(lodash.max([1,2])).toBe(2)
})
测试(jest)输出:
Cannot read properties of undefined (reading 'max')
TypeError: Cannot read properties of undefined (reading 'max')
jest.config.js:
/** @type {import('ts-jest').JestConfigWithTsJest} */
const tsconfig = require('./tsconfig.json')
const moduleNameMapper = require('tsconfig-paths-jest')(tsconfig)
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper,
}
webpack.config.js:
const path = require('path')
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin').default
const nodeExternals = require('webpack-node-externals')
module.exports = {
entry: './src/server.ts',
target: 'node',
externals: [nodeExternals()],
devtool: 'source-map',
mode: process.env.RUNTIME_ENV === 'production' ? 'production' : 'development',
module: {
rules: [
{
test: /\.(ts|js)$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.(graphql|gql)$/,
loader: '@graphql-tools/webpack-loader',
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
plugins: [new TsconfigPathsPlugin({})],
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
}
tsconfig.json:
{
"compilerOptions": {
"lib": ["ESNext"],
"moduleResolution": "node",
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": true,
"sourceMap": true,
"target": "ES2020",
"outDir": "lib",
"isolatedModules": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": ".",
"allowJs": true,
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*.ts","./global.d.ts"],
"exclude": [
"node_modules/**/*",
"_warmup/**/*",
".vscode/**/*"
]
}
答案#1
在我的情况下,问题出在导入 CommonJS/AMD/UMD 模块。我在 tsconfig.json 中缺少 "esModuleInterop": true
这个话题帮到了我: https://github.com/vercel/ms/issues/186
答案#2
在使用 Nrwl/Nx 的情况下,它默认为 SWC 编译,这种编译方式与 ts-jest 不同。这导致在测试中出现未定义的导入,尤其是在导入没有使用星号的情况下 import stuff from 'stuff'。要修复此问题,你可以使用 import * as stuff from 'stuff',但是这样代码在运行时会失败。
esModuleInterop 导致这种特定情况可以工作,但其他情况会失败。唯一的解决办法是将 @swc/register 移除为依赖项。