Jest and Babel transpilation - SyntaxError: Cannot use import statement outside a module

Jest and Babel transpilation - SyntaxError: Cannot use import statement outside a module

我很难在某些情况下使用 JEST 运行我得到的测试

测试套件未能 运行

...node_modules\p-retry\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import retry from 'retry';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

    > 1 | import pRetry from 'p-retry';
        | ^
      2 |
      3 | export function Retry(tries: number) {

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
      at Object.<anonymous> (src/common/Retry.ts:1:1)

与此同时,我的 webpack 构建与 typescript 和 babel 配合得很好。我尝试了很多东西(见下文让它工作但到目前为止没有成功 - 并且还没有真正能够理解发生了什么。从我的观点来看 - 尽管到目前为止转译的东西对我来说是一个黑色区域我试图让 Jest 能够使用 ESModules 并提供代码,并尝试提供 commonJS 模块代码。

所以我正在寻找替代方案和方法来进一步调查。特别是有一件事让我感到奇怪: 错误中的 Retry.ts 文件是我导入 pRetry(以 ESModule 样式编写的 node_module)的文件之一,它在其代码中从 'retry'(另一个节点模块)导入重试以 commonJS 风格编写)从错误的第一行开始。

所以在我身上发生的事情似乎是 pRetry 不是从它的 ESModule 代码转换而来的(pRetry 的源代码以 import retry from 'retry'; 开头),而是包含在一些 commonJS 代码中,而不是如果我正确解释语法。

所以我接下来的步骤可能是调查 babel-jest 真正生成的内容并检查那里有什么并尝试进一步推导。有没有人知道如何实现这个(特别是了解 babel-jest 生成的内容)或有其他想法?

我尝试过的事情 - 都失败了(有时错误略有不同)

  1. 使用插件:["@babel/plugin-transform-runtime"] babel.config.js
  2. 将 tsconfig.json 中的目标和模块更改为 es5
  3. 在下面介绍 jest.config.ts transformIgnorePatterns: ["node_modules/?!(p-retry)"]
  4. 在 jest.config.ts
  5. 中使用以下内容

preset: "ts-jest",
transform: { '^.+\.(ts|tsx)?$': 'ts-jest', "^.+\.(js|jsx)$": "babel-jest"}

或者两者都使用 ts-jest 或两者都使用 babel-jest

  1. 按照一位 post

    的建议从 .babelrc 文件迁移到 babel.config.js
  2. AllowJS:在 tscfonfig.json 中为 true,在开玩笑中结合使用 transformIgnorePatterns

  3. 将 ["@babel/plugin-transform-runtime",{"regenerator": true}] 添加到 babel.config

  4. 正在使用

    预设:“ts-jest”,
    测试环境:“节点”, 转换:{"node_modules/p-retry/.+\.(j|t)sx?$": "ts-jest"},
    transformIgnorePatterns: ["node_modules/(?!p-retry/.*)"]

在jest.config

  1. 在babel.config
  2. 中使用“transform-es2015-modules-commonjs”
  3. 在babel.config
  4. 中使用@babel/plugin-transform-modules-commonjs
  5. 按照
  6. 的建议应用以下步骤
  1. 在 jest.config.ts
  2. 中使用 jest-environment-node、node 或 jsdom 等测试环境

开玩笑-config.ts:

const tsconfig = require("./tsconfig.json");
const moduleNameMapper = require("tsconfig-paths-jest")(tsconfig)

export default {
   collectCoverage: true,
   coverageDirectory: "analysis/coverage",
   coveragePathIgnorePatterns: ["/node_modules/"],
   collectCoverageFrom: ["src/**/*.{js,jsx,ts}"],
   coverageReporters: ["json", "lcov", "text", "clover"],
   coverageThreshold: {
      global: {
         branches: 0,
         functions: 0,
         lines: 0,
         statements: 0
      },
   },
   clearMocks: true,
   coverageProvider: "babel",
   moduleNameMapper,
   roots: ["<rootDir>/src/", "<rootDir>/test/"],
   testEnvironment: 'jest-environment-node', 
   testPathIgnorePatterns: [
      "\\node_modules\\"
   ],
   "transform": {
      "^.+\.(js|ts|jsx)$": "babel-jest"
   }
};

babel.config.js:

    module.exports = {
   presets: ['@babel/preset-typescript',
      ['@babel/preset-env', {
         targets: { node: "current" }
      }],
      '@babel/preset-flow',

   ],
   plugins: [["@babel/plugin-transform-modules-commonjs"], ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties"]]
}

摘自package.json

"@babel/core": "^7.16.12",
"@babel/plugin-proposal-decorators": "^7.16.5",
"@babel/plugin-transform-modules-commonjs": "^7.16.8",
"@babel/plugin-transform-runtime": "^7.16.10",
"@babel/preset-env": "^7.14.4",
"@babel/preset-flow": "^7.16.7",
"@babel/preset-typescript": "^7.13.0",
"@babel/runtime": "^7.16.7",
"babel-jest": "^27.4.6",
"babel-plugin-transform-regenerator": "^6.26.0",         
"jest": "^27.0.4",
"jest-config": "^27.4.5",
"jest-esm-transformer": "^1.0.0",
"ts-jest": "^27.1.3",
"tsconfig-paths-jest": "^0.0.1",
"core-js": "^3.20.0",

原来我很接近。

通过添加 esmodules: false 更改 babel.config.ts 就完成了:-)

module.exports = {
   presets: ['@babel/preset-typescript',
      ['@babel/preset-env', {
         targets: { esmodules: false, node: "current" }
      }],
      '@babel/preset-flow',
    
   ],
   plugins: [["@babel/plugin-transform-modules-commonjs"], ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties"]]
}

你可以让 Jest 不忽略转换 p-retry 通过在你的笑话中添加这个。 config.js,对我有用。

  "transformIgnorePatterns": [
"node_modules/(?!(p-retry)/)",

],