【问题标题】:Why can't Jest find my TypeScript modules?为什么 Jest 找不到我的 TypeScript 模块?
【发布时间】:2022-01-09 23:27:20
【问题描述】:

我正在使用 Jest 和 Babel 的组合来测试我的 TypeScript 项目。直到最近,我还在使用不带扩展名的导入(正如 TypeScript error you get when trying to use a .ts extension 所推荐的那样)。该组合在 Jest 中运行良好,但在编译时,生成的文件在其导入时仍然没有扩展名,因此无法执行。

我更改为在我的导入中使用 .js 扩展,它仍然可以在 Jest 之外运行,并且在编译时产生可用的输出,但现在 Jest 无法再找到我的 TypeScript 模块:

$ npx jest
 FAIL  src/__test__/index.test.ts
  ● Test suite failed to run

    Cannot find module '../index.js' from 'src/__test__/index.test.ts'

    > 1 | import { foobar } from '../index.js';
        | ^
      2 |
      3 | describe('index', () => {
      4 |   it('works', () => {

      at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:324:11)
      at Object.<anonymous> (src/__test__/index.test.ts:1:1)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |       0 |        0 |       0 |       0 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.526 s
Ran all test suites.

我什至尝试拆分差异并在我的源文件中包含扩展名并在我的测试中省略它们,但它只是将错误从测试文件移动到源文件。

我的配置如下:

babel.config.json

{
  "presets": [
    [
      "@babel/preset-env",
      { "targets": { "esmodules": true }, "modules": false }
    ],
    ["@babel/preset-typescript", { "onlyRemoveTypeImports": true }]
  ],
  "env": {
    "test": {
      "presets": [["@babel/preset-env", { "targets": { "esmodules": true } }]],
      "sourceMaps": true
    }
  }
}

jest.config.json

{
  "collectCoverage": true,
  "coverageDirectory": "coverage",
  "coverageProvider": "v8",
  "errorOnDeprecated": true,
  "resetMocks": true,
  "restoreMocks": true
}

package.json

{
  "name": "repro-jbt",
  "version": "0.1.0",
  "description": "A reproduction of an issue with Jest, Babel, and TypeScript.",
  "type": "module",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc && babel --extensions '.ts' --ignore '**/__test__/*' --source-maps --out-dir dist src",
    "test": "jest"
  },
  "license": "BSD-3-Clause",
  "devDependencies": {
    "@babel/cli": "^7.16.7",
    "@babel/preset-env": "^7.16.7",
    "@babel/preset-typescript": "^7.16.7",
    "@types/jest": "^27.4.0",
    "jest": "^27.4.7",
    "ts-node": "^10.4.0",
    "typescript": "^4.5.4"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "alwaysStrict": true,
    "declaration": true,
    "emitDeclarationOnly": true,
    "exactOptionalPropertyTypes": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "moduleResolution": "node",
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noUncheckedIndexedAccess": true,
    "outDir": "dist/",
    "strict": true,
    "target": "ESnext"
  },
  "exclude": ["**/__test__/*"],
  "include": ["src/"]
}

如何编写在编译和测试时都有效的导入?我是否配置错误?

【问题讨论】:

    标签: typescript jestjs babeljs


    【解决方案1】:

    我几乎 100% 确信这不是预期的解决方案,但它确实对我有用。

    向我的 Jest 配置添加自定义解析器允许我即时重写导入路径,将源目录中的文件的 .js 更改为 .ts

    jest.config.json

    {
      "collectCoverage": true,
      "coverageDirectory": "coverage",
      "coverageProvider": "v8",
      "errorOnDeprecated": true,
      "resetMocks": true,
      "resolver": "<rootDir>/jest.resolver.cjs",
      "restoreMocks": true
    }
    

    jest.resolver.cjs

    const path = require('path');
    
    module.exports = function (request, options) {
      let realPath = request;
    
      if (
        new RegExp(`${options.rootDir}/src/`).test(
          path.resolve(options.basedir, realPath),
        )
      ) {
        realPath = realPath.replace('.js', '.ts');
      }
    
      return options.defaultResolver(realPath, options);
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-18
      • 2013-10-13
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 2019-08-16
      相关资源
      最近更新 更多