Node / Express 别名与 Jest

Node / Express Aliases with Jest

我目前正在配置文件路径别名以简化项目内的相对路径导入。在本地 运行ning 时,我的一切都运行良好。这是一些上下文:

tsconfig.json

{
  "compilerOptions": {
    "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "lib": [
      "ES2020.Promise"
    ],                             /* Specify library files to be included in the compilation. */
    "allowJs": true, /* Allow javascript files to be compiled. */
    "outDir": "./build", /* Redirect output structure to the directory. */
    "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    "strict": true, /* Enable all strict type-checking options. */
    "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
    "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "baseUrl": "./src",                       /* Base directory to resolve non-absolute module names. */
    "paths": {
      "@models/*": ["models/*"],
      "@services/*": ["server/services/*"],
      "@spikeball-api/types/*": ["server/types/*"],
    },
    "types": ["jest", "node"],                           /* Type declaration files to be included in compilation. */
    "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": [
    "src/**/*",
    "decs.d.ts",
  ],
  "exclude": [
    "node_modules"
  ],
  "ts-node": {
    "files": true,
    "transpileOnly": true
  }
}

我的 package.json 有以下内容:

  "_moduleAliases": {
    "@models": "build/models",
    "@services": "build/server/services",
    "@spikeball-api/types": "build/server/types",
    "@spikeball-api/graphql": "build/server/app/graphql"
  },

我的jest.config.ts是:

import type { Config } from '@jest/types'
import jestModuleNameMapper from "jest-module-name-mapper"

// For possible configuration options see: https://jestjs.io/docs/configuration
// Sync object
const config: Config.InitialOptions = {
  preset: "ts-jest",
  testEnvironment: "node",
  verbose: true,
  forceExit: true,
  // clearMocks: true,
  roots: [
    "<rootDir>/src"
  ],
  testMatch: [
    // "**/__tests__/**/*.+(ts|tsx|js)",
    // "**/?(*.)+(spec|test).+(ts|tsx|js)",
    // When wanting to only test one file for simplicity purposes or test suite debugging
    // "**/**/__tests__/app/graphql/posts/mutation/likePost.test.ts",
    "**/**/__tests__/models/Badge.test.ts",
  ],
  transform: {
    "^.+\.(ts|tsx)$": "ts-jest"
  },
  coverageDirectory: "<rootDir>/coverage",
  collectCoverage: true,
  collectCoverageFrom: [
    "**/*.{js,jsx}",
    "**/*.{ts,tsx}",
    "!**/node_modules/**",
    "!**/vendor/**",
    "!**/__tests__/**",
  ],
  /* This should be used when implementing CI tests for PR and merge checks */
  // coverageThreshold: {
  //   global: {
  //     branches: 80,
  //     functions: 80,
  //     lines: 80,
  //     statements: -10
  //   }
  // },
  globalSetup: "<rootDir>/src/__tests__/setup/setup.api.ts",
  setupFiles: [
    "<rootDir>/src/__tests__/setup/setupFile.ts"
  ],
  testPathIgnorePatterns: [
    "<rootDir>/src/__tests__/setup"
  ],
  moduleFileExtensions: ["js", "jsx", "ts", "tsx", "graphql", "json", "node"],
  // For mapping module aliases
  moduleNameMapper: {
    "@models/*(.*)": "<rootDir>/src/models/",
    "@services/*(.*)": "<rootDir>/src/server/services/",
    "@spikeball-api/types/*(.*)": "<rootDir/src/server/types/",
  }
}

export default config

我不断收到的错误:

Error: Jest: Got error running globalSetup - /Users/shanekeney/Documents/Spikeball/spikeball-api/src/__tests__/setup/setup.api.ts, reason: Cannot find module '@spikeball-api/types/graphql'
Require stack: ...

所以这显然与别名有关。只有当 运行 宁开玩笑时,当我 运行 服务器具有以下内容时,一切都在本地开发中正常工作:nodemon --exec ts-node src/server/app.ts, `。 我已经尝试了几种不同的解决方案,这些解决方案来自所有类型的组合与 jest config 正则表达式模式。任何帮助将不胜感激。

通过执行以下操作解决了此问题:

已将 import 'tsconfig-paths/register'; 添加到我的 globalSetup 文件的顶部。这是我的愚蠢错误,因为我没有考虑在我的测试环境之外进行 jest 全局设置 运行,所以我在应用程序入口中设置的链接导入不适用于设置文件。

我也很确定 jest.config.tsmoduleNameMapper 文件别名的格式有误,所以我最终使用了一个库来为我处理映射:

import jestModuleNameMapper from "jest-module-name-mapper"

...

// And then just use the function as follows in your jest.config.ts

moduleNameMapper: jestModuleNameMapper()