开玩笑无法解析模块别名

时间:2019-10-16 09:24:25

标签: node.js typescript unit-testing jestjs alias

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

tsconfig.json

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

package.json

  ...
 "_moduleAliases": {
    "@config": "src/config",
    "@interface": "src/interface",
    "@services": "src/services"
  },
  "jest": {
    "moduleNameMapper": {
      "@config/(.*)": "src/config/$1",
      "@interface/(.*)": "src/interface/$1",
      "@services/(.*)": "src/services/$1"
    },

     "moduleFileExtensions": ['js', 'json', 'jsx', 'ts', 'tsx', 'node']
  },
...

server.ts

import { logger } from '@config/logger';

运行npm start时一切正常,但运行笑话时却出现错误

FAIL  src/test/article.spec.ts
  ● Test suite failed to run

    Cannot find module '@config/logger' from 'server.ts'

    However, Jest was able to find:
        'rest/server.ts'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

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

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

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

module.exports = {
  "roots": [
    "<rootDir>/src/"
],
  "transform": {
    "^.+\\.tsx?$": "ts-jest"
  }

}

并更新package.json中的moduleNameMapper:

...
  "_moduleAliases": {
    "@config": "./src/config",
    "@interfaces": "./src/interfaces",
    "@services": "./src/services"
  },
  "jest": {

    "moduleNameMapper": {
      "@config/(.*)": "<rootDir>/src/config/$1",
      "@interfaces/(.*)": "<rootDir>/src/interfaces/$1",
      "@services/(.*)": "<rootDir>/src/services/$1"
    }
  }
...

2 个答案:

答案 0 :(得分:3)

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

我的应用属于以下堆栈:

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

要点:

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

首先,使用

https://www.npmjs.com/package/module-alias安装module-alias
npm i --save module-alias

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

require('module-alias/register')

module-alias 文档所示。然后设置tsconfig.ts。请记住,baseUrl 在这里也很重要:

{
 "compilerOptions": {
    "baseUrl": ".",
    ...
    "paths": {
      "@helpers/*": ["src/helpers/*"],
      "@root/*": ["src/*"]
      ...
    }
 }

然后设置您的 webpack.js

const path = require('path')
...
{
  resolve: {
    ...
    alias: {
      '@helpers': path.resolve(__dirname, 'src', 'helpers'),
      '@root': path.resolve(__dirname, 'src')
    }
  }
}

然后设置您的 package.json

{
   ...
   "_moduleAliases": {
     "@helpers": "src/helpers",
     "@root": "src"
   }
}

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

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

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

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

因此考虑到您的构建命令只是:

tsc

现在变成了

tsc && tscpaths -p tsconfig.json -s ./src -o ./dist/server

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

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

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

import { IApiResponse } from '@intf/IApi'

答案 1 :(得分:0)

我认为您在tsconfig中没有正确配置路由,因为路径缺少src文件夹(它们出现在package.json模块别名config中):

您的tsconfig代码:

"@config/*": ["config/*"],
"@interfaces/*": ["interfaces/*"],
"@services/*": ["services/*"]

我认为应该是:

"@config/*": ["src/config/*"],
"@interfaces/*": ["src/interfaces/*"],
"@services/*": ["src/services/*"]