jest 无法解析模块别名

Eko*_*oar 13 alias unit-testing node.js typescript jestjs

我正在使用一个名为 module-alias 的 npm 模块。我在 tsconfig.json 和 package.json 中映射一些模块

\n\n

tsconfig.json

\n\n
"compilerOptions": {\n   "baseUrl": "./src",\n   "paths": {\n   "@config/*": ["config/*"],\n   "@interfaces/*": ["interfaces/*"],\n   "@services/*": ["services/*"]\n  },\n  "module": "commonjs",\n  "target": "es2015",                   /* Specify module code generation: \'none\', \'commonjs\', \'amd\', \'system\', \'umd\', \'es2015\', or \'ESNext\'. */\n  "sourceMap": true,\n  "outDir": "./dist",                        /* Redirect output structure to the directory. */\n  "rootDir": "./src",    \n  "allowSyntheticDefaultImports": true          /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

包.json

\n\n
  ...\n "_moduleAliases": {\n    "@config": "src/config",\n    "@interface": "src/interface",\n    "@services": "src/services"\n  },\n  "jest": {\n    "moduleNameMapper": {\n      "@config/(.*)": "src/config/$1",\n      "@interface/(.*)": "src/interface/$1",\n      "@services/(.*)": "src/services/$1"\n    },\n\n     "moduleFileExtensions": [\'js\', \'json\', \'jsx\', \'ts\', \'tsx\', \'node\']\n  },\n...\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

服务器.ts

\n\n
import { logger } from \'@config/logger\';\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我运行时一切正常npm start,但当我运行 jest 时它给我一个错误

\n\n
FAIL  src/test/article.spec.ts\n  \xe2\x97\x8f Test suite failed to run\n\n    Cannot find module \'@config/logger\' from \'server.ts\'\n\n    However, Jest was able to find:\n        \'rest/server.ts\'\n\n    You might want to include a file extension in your import, or update your \'moduleFileExtensions\', which is currently [\'js\', \'json\', \'jsx\', \'ts\', \'tsx\', \'node\'].\n
Run Code Online (Sandbox Code Playgroud)\n\n

有人知道问题是什么吗?谢谢

\n\n

解决方案对我有用(更新 18/10/2019):

\n\n

使用以下代码创建 jest.config.js:

\n\n
module.exports = {\n  "roots": [\n    "<rootDir>/src/"\n],\n  "transform": {\n    "^.+\\\\.tsx?$": "ts-jest"\n  }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

并更新 package.json 中的 moduleNameMapper:

\n\n
...\n  "_moduleAliases": {\n    "@config": "./src/config",\n    "@interfaces": "./src/interfaces",\n    "@services": "./src/services"\n  },\n  "jest": {\n\n    "moduleNameMapper": {\n      "@config/(.*)": "<rootDir>/src/config/$1",\n      "@interfaces/(.*)": "<rootDir>/src/interfaces/$1",\n      "@services/(.*)": "<rootDir>/src/services/$1"\n    }\n  }\n...\n
Run Code Online (Sandbox Code Playgroud)\n

Gre*_*Woz 16

几个小时后,我成功地完成了这项工作。我会尽力简化它,以节省其他人的时间并使其顺利。

我的应用程序属于以下堆栈:

  • 用于 API 构建的Typescript(tsc并且没有 Babel)( )ts-node/register.ts
  • React(.tsx使用 Webpack)
  • jest用于 API 测试(无 Babel)
  • testcafe用于UI/E2E
  • VSCode 作为 IDE

主要注意事项:

  1. 对我有用的解决方案是别名前面必须有“ @ ”字符。理论上这不是必需的module-alias,但是当我们应用模块名称映射器时,Jest 就会迷失方向。
  2. “webpack”别名和“tsconfig”之间的命名需要保持一致。VSCode 必须不要在 TSX 文件中的模块名称上添加红色下划线
  3. 无论您的文档结构如何,这都应该有效,但baseUrl如果遇到问题,请记住进行调整和开玩笑配置。
  4. 在 VSCode 中对.tsx文件应用更改时,不必担心某些路径带有下划线。这是暂时的,因为 VSCode 似乎只有在所有文件都正确相互连接时才能掌握它。一开始这让我失去了动力。

首先,module-aliashttps://www.npmjs.com/package/module-alias安装

npm i --save module-alias
Run Code Online (Sandbox Code Playgroud)

然后添加到您的初始启动文件(.ts仅适用于文件,即您的应用程序服务器):

require('module-alias/register')
Run Code Online (Sandbox Code Playgroud)

正如module-alias文档所示。然后设置tsconfig.ts。请记住,baseUrl这里也相关:

{
 "compilerOptions": {
    "baseUrl": ".",
    ...
    "paths": {
      "@helpers/*": ["src/helpers/*"],
      "@root/*": ["src/*"]
      ...
    }
 }
Run Code Online (Sandbox Code Playgroud)

然后设置你的webpack.js

const path = require('path')
...
{
  resolve: {
    ...
    alias: {
      '@helpers': path.resolve(__dirname, 'src', 'helpers'),
      '@root': path.resolve(__dirname, 'src')
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后设置你的package.json

{
   ...
   "_moduleAliases": {
     "@helpers": "src/helpers",
     "@root": "src"
   }
}
Run Code Online (Sandbox Code Playgroud)

然后设置您的jest配置(我仅附加应用更改时相关的内容):

{
   rootDir: ".",
   roots: ["./src"],
   transform: {
     "^.+\\.ts?$": "ts-jest"
   },
   moduleNameMapper: {
     "@helpers/(.*)": "<rootDir>/src/helpers/$1",
     "@root/(.*)": "<rootDir>/src/$1"
   },
   ...
 }
Run Code Online (Sandbox Code Playgroud)

现在,我们需要处理构建过程,因为tsc无法将别名转换为其相对的兄弟姐妹。

为此,我们将使用tscpaths包: https: //github.com/joonhocho/tscpaths。这个很简单。

所以考虑你的构建命令只是:

tsc
Run Code Online (Sandbox Code Playgroud)

现在变成了

tsc && tscpaths -p tsconfig.json -s ./src -o ./dist/server
Run Code Online (Sandbox Code Playgroud)

您需要调整您的-s-o到您的结构,但是当您在.js构建后检查文件时,您应该查看相对路径是否正确链接(并相应地进行调试)。

就是这样。它应该像王牌一样工作。虽然很多,但还是值得的。

控制器 (.ts) 和 React 组件 (.tsx) 文件中的调用示例:

import { IApiResponse } from '@intf/IApi'
Run Code Online (Sandbox Code Playgroud)

  • “moduleNameMapper”就是为我做的,谢谢您的回复! (2认同)

小智 5

就我而言,为了支持@Greg Wozniak 的答案,我只需要修复我的笑话配置文件。

我的应用程序使用jest.config.ts

在我的 src/index.ts我有import "module-alias/register"

package.json

{
   ...
   "_moduleAliases": {
     "@helpers": "dist/helpers",
     "@root": "dist"
   }
}
Run Code Online (Sandbox Code Playgroud)

tsconfig.json

{
 "compilerOptions": {
    "baseUrl": "./src",
    ...
    "paths": {
      "@helpers/*": ["helpers/*"],
      "@root/*": ["*"]
      ...
    }
 }
Run Code Online (Sandbox Code Playgroud)

jest.config.ts

  • 在 moduleNameMapper* 中添加了根、预设、(.*)和符号$1
{
   roots: [
        "<rootDir>/src/"
    ],
    preset: "ts-jest",
   transform: {
        "^.+\\.(ts|tsx)$": "ts-jest",
    },
   moduleNameMapper: {
     "@helpers/(.*)": "<rootDir>/src/helpers/$1",
     "@root/(.*)": "<rootDir>/src/$1"
   },
   ...
 }

Run Code Online (Sandbox Code Playgroud)