网站搜索

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 移除为依赖项。