使用 ts-jest 和 webpack 允许 Jest 识别和解析模块别名需要啥?

Posted

技术标签:

【中文标题】使用 ts-jest 和 webpack 允许 Jest 识别和解析模块别名需要啥?【英文标题】:What is necessary to allow Jest, using ts-jest and webpack, to recognize and parse module aliases?使用 ts-jest 和 webpack 允许 Jest 识别和解析模块别名需要什么? 【发布时间】:2019-10-19 11:39:37 【问题描述】:

我有一个要测试的.ts 文件。

前端/游戏/index.ts

import App from '@/views/app';
let app = new App(
  el: "#app",
);
export default app;

我想在index.ts 中导入的文件是 frontend/game/views/app.vue 。 Webpack-dev-server、eslint 和(我假设)ts-loader 都能够使用 @ 别名解析模块导入,因为我的构建或开发步骤中没有错误。

但是,当我运行 jest 时,出现以下错误:

   TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
    frontend/game/index.ts:1:17 - error TS2307: Cannot find module '@/views/app'.

    1 import App from '@/views/app';
                      ~~~~~~~~~~~~~

它指的是我的file.spec.js文件的第一行:

frontend/tests/game/models/file.spec.js

import App from '@/views/app';

我遵循了typescript module resolution documentation, 和articles specifically about setting up webpack/typescript/jest projects. 的建议

他们的建议通常围绕在 3 个地方设置别名:

    webpack 配置,在resolve.alias 下。我的:

webpack.config.js

module.exports = 
  entry: './frontend/game/index.ts',
  output: 
    filename: 'main.js',
    path: path.resolve(__dirname, 'staticfiles')
  ,
  resolve: 
    extensions: [ '.ts', '.js', '.vue', '.scss', '.sass'],
    alias: 
      'vue$': 'vue/dist/vue.esm.js',
      '@': path.resolve(__dirname, 'frontend/game/')
    
  ,
    Jest 配置,在 moduleNameMapper 下。我的:

package.json(我的笑话配置所在的位置)

 "jest": 
    "verbose": true,
    "moduleFileExtensions": [
      "js",
      "json",
      "vue",
      "ts"
    ],
    "moduleDirectories": [
      "node_modules",
      "<rootDir>/frontend/game"
    ],
    "transform": 
      ".*\\.(vue)$": "vue-jest",
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      "^.+\\.ts$": "<rootDir>/node_modules/ts-jest"
    ,
    "moduleNameMapper": 
      "^@/(.*)$": "<rootDir>/frontend/game/$1",
      "\\.(css|less|sass|scss)$": "<rootDir>/frontend/tests/styleMock.js",
      "\\.(gif|ttf|eot|svg)$": "<rootDir>/frontend/tests/fileMock.js"
    ,
    "transformIgnorePatterns": [
      "/node_modules/(?!local-echo).+\\.js$"
    ]
  ,
    Typescript 配置,利用 baseUrl 结合 paths。我的:

tsconfig.json


  "compilerOptions": 
    "outDir": "./built/",
    "sourceMap": true,
    "strict": false,
    "noImplicitReturns": true,
    "module": "es2015",
    "moduleResolution": "node",
    "target": "es5",
    "esModuleInterop": true,
    "baseUrl": ".",
    "paths": 
      "@/*": ["frontend/game/*"]
    
  ,
  "include": [
    "./frontend/**/*"
  ]

据我所知,我完全按照说明进行操作。在 github 和 *** 上窥探之后,我没有发现我做错了什么,或者现在是否有一些错误。我已经尝试将.vue 扩展添加到导入,尝试各种路径实验组合(即从paths 对象中删除“前端”,放置和替换路径前和路径后的斜杠等),并切换设置,例如作为esModuleInterop,无济于事。

如何让 Jest 识别我的模块别名?

编辑:有趣的是,在 import 语句之前添加 //@ts-ignore 会导致此错误“消失”,然后 jest 成功导入文件。

EDIT2:tsignore 步骤让我怀疑 jest 是否能够导入 .vue 文件,因此我在 this issue on github 以及 .vue 文件上的 typescript recommendations 中进行了探索。但是,我已经有一个与他们的建议相同的vue-shims.d.ts 文件。只是为了实验,我把它复制到整个应用程序,但无论我放在哪里,都没有效果。

【问题讨论】:

【参考方案1】:

你需要添加一个jest.config.jsmodulesNameMapper 配置匹配你的Webpack。 看看这篇容易理解的文章:https://alexjover.com/blog/enhance-jest-configuration-with-module-aliases/

【讨论】:

以上是关于使用 ts-jest 和 webpack 允许 Jest 识别和解析模块别名需要啥?的主要内容,如果未能解决你的问题,请参考以下文章

Jest、Typescript、ts-jest:覆盖范围略有不正确

ts-jest:TypeScript 类型错误被忽略

无法使用 ts-jest 转换 node_modules 中的文件夹

TypeScript ts-jest 预处理器的目的是啥?

React Jest 测试无法使用 ts-jest 运行 - 导入文件上出现意外令牌

Jest,ts-jest,带有 ES 模块导入的打字稿:找不到模块