如何在 Jest 中创建嵌套的 moduleNameMapper?

Rol*_*rov 6 typescript jestjs ts-jest

我的简化jest.config.js是:

module.exports = {
  preset: "ts-jest",
  collectCoverage: true,
  collectCoverageFrom: [
    "src/**/*.ts",
    "!**/node_modules/**",
    "!src/config/*.ts",
    "!build/**/*"
  ],
  coverageReporters: ["text"],
  reporters: ["default"],
  moduleDirectories: [
    "src",
    "node_modules"
  ],
  moduleNameMapper: {
    "@helpers/(.*)": "<rootDir>/src/helpers/$1", <---- question about this
  },
  globals: {
    'ts-jest': {
      diagnostics: {
        pathRegex: /\.(spec|test)\.ts$/,
        ignoreCodes: [6133]
      }
    }
  },
  verbose: true,
  roots: ["src"],
  moduleFileExtensions: ["ts", "tsx", "js", "jsx"]
};

Run Code Online (Sandbox Code Playgroud)

moduleNameMapper 映射到任何级别的嵌套路径:

  • @helpers/foo
  • @helpers/foo/foo
  • ETC...

我在测试中使用它,例如import foo from "@helpers/foo/foo";

但是,我收到此错误:

无法找到@helpers/foo映射为的模块: /<PATH>/src/helpers/foo

在文档中没有找到有关嵌套路径的任何内容。我认为,由于@helpers/(.*)是正则表达式,因此它应该可以开箱即用。

我究竟做错了什么?也许这是一个错误?

Sly*_*tis 1

不知道你是否解决了这个问题,但我也遇到了同样的问题。当我使用打字稿时,我还必须将路径添加到我的 tsconfig 中,以便它理解所有上下文中的映射,此外,在使用相对路径时,您可能必须更新其 rootDir。

这在测试我的电子/svelte应用程序时对我有用:

//jest.config.js
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  cacheDirectory: '.jest',
  transform: {
    '^.+\\.svelte$': 'svelte-jester',
  },
  moduleFileExtensions: [
    'js', 'ts', 'svelte'
  ],
  globals: {
    'ts-jest': {
      tsconfig: '<rootDir>/tests/tsconfig.json'
    }
  },
  moduleNameMapper: {
    '^@app/(.*)$': '<rootDir>/app/$1',
    '^@main/(.*)$': '<rootDir>/app/main/src/$1',
    '^@preload/(.*)$': '<rootDir>/app/preload/src/$1',
    '^@renderer/(.*)$': '<rootDir>/app/renderer/src/$1',
    '^@test/(.*)$': '<rootDir>/tests/$1',
    'electron': '<rootDir>/tests/mock/electron.ts'
  }
}
Run Code Online (Sandbox Code Playgroud)

我对将 tsconfig 路径映射到 moduleNameMapper 的实用程序方法有一些问题,所以我只是直接引用它。(以下 tsconfig 来自 /tests 文件夹本身):

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "useDefineForClassFields": true,
    "strict": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "isolatedModules": false,
    "allowJs": true,
    "noFallthroughCasesInSwitch": false,
    "noImplicitAny": false,
    "lib": ["esnext", "dom"],
    "types": ["node", "vite/client"],
    "paths": {
      "@main/*": ["../app/main/src/*"],
      "@test/*": ["./*"],
      "@renderer/*": ["../app/renderer/src/*"],
      "@preload/*": ["../app/preload/src/*"]
    },
    "rootDirs": [".", "../app"]
  },
  "include": [
    "./**/*.d.ts",
    "./**/*.ts",
    "../node_modules/@types/jest/index.d.ts"
  ]
}
Run Code Online (Sandbox Code Playgroud)