【问题标题】:Jest won't transform the module - SyntaxError: Cannot use import statement outside a moduleJest 不会转换模块 - SyntaxError: Cannot use import statement outside a module
【发布时间】:2020-08-30 00:54:50
【问题描述】:

无论我如何尝试,我都无法摆脱这个SyntaxError: Cannot use import statement outside a module 错误,这让我非常沮丧。有没有人在这里解决这个问题?我已经阅读了一百万个 stackoverflow 和 github 问题线程。没有明确的解决方案。

这是一个 React、Typescript、Webpack 项目。我正在尝试测试一个模块。但是 Jest 不会以某种方式将 模块转换为纯 javascript

我得到的错误是

/Users/me/dev/Project/project/node_modules/variables/src/variables.js:12
    import './main.js';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      17 | 
      18 | */
    > 19 | import { GlobalVars } from 'variables'
         | ^
      20 | 
      21 | export const Vars = new GlobalVars()
      22 | 

我试图解决这个问题(但没有奏效):

  • babel.config 中使用env 设置:env.test.preset: ['@babel/plugin-transform-modules-commonjs']

  • 将 Jest 配置中的 transform 设置修改为 '^.+\\.jsx?$': 'babel-jest', '^.+\\.tsx?$': 'ts-jest' 以及与此相关的所有其他可能性。

  • 在 Jest 配置中,testPathIgnorePatternstransformIgnorePatterns

  • 使用.babel.config.js 代替.babelrc.js

...还有更多。

我有这个设置:

package.json

  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node"
  }

.babelrc.js

module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { node: 'current' } }],
    '@babel/preset-react',
    '@babel/preset-typescript',
  ],
  plugins: [
    '@babel/plugin-transform-runtime',
    '@babel/proposal-class-properties',
    '@babel/transform-regenerator',
    '@babel/plugin-transform-template-literals',
    'react-hot-loader/babel',
  ],
}

variables.ts

import { GlobalVars } from 'variables'

export const Vars = new GlobalVars()

variables.spec.ts

import { Vars } from './variables.ts'

describe('Test The Package', () => {
  it('Should accept new variables', () => {
    Vars.newVariable = 'new variable'
    expect(Vars.newVariable).toEqual('new variable')
  })
})

知道如何解决这个问题吗?

【问题讨论】:

标签: typescript jestjs babel-jest ts-jest


【解决方案1】:

尽管我已经单独尝试过它们,但我还没有一起尝试过它们(transformtransformIgnorePatterns)。所以这个笑话配置解决了我的问题:

  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node",
    "transform": {
      "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!variables/.*)"
    ]
  },

我的错误是:

  1. 不使用transformtransformIgnorePatterns一起
  2. 并将babel-jest定义为转换器而不是ts-jest(我想当jest的preset定义为ts-jest时会出现问题。因为如果我将其更改为@ 987654330@ 再次抛出同样的错误。):
--- "node_modules/variables/.+\\.(j|t)sx?$": "babel-jest"
+++ "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"

【讨论】:

  • 我应用了这个解决方案,效果很好,非常感谢!
  • 我很高兴它有帮助!
  • 对于使用 babel 而不是 ts-jest 的任何人,也将您的 .babelrc 重命名为 babel.config.json 参见:babeljs.io/docs/en/configuration#whats-your-use-case 如果您已经在使用 babel,则可能不需要额外的转换。
  • 哪个笑话配置?有一个 jest.config.js 文件,在 package.json 中有一个 jest config 部分。这个配置到底在哪里?
  • 超级!。我已经在 package.json 中完成了这个配置并且它有效。谢谢
【解决方案2】:

由于 Jest 不能很好地使用 esmodules,您需要在 jest.config.js 中添加这些配置,以告诉 Jest 改用 commonJS 构建

moduleNameMapper: {
  '^variables$': 'variables/dist/cjs',
  '^[NAME OF MODULE YOU WANT TO IMPORT]$': '[NAME OF MODULE YOU WANT TO IMPORT]/dist/cjs'
}

【讨论】:

    【解决方案3】:

    另一种解决方法是使用ts-jest,引用自Jest's getting started

    但是,将 TypeScript 与 Babel 结合使用有一些注意事项。因为 Babel 中的 TypeScript 支持纯粹是转译,所以 Jest 不会在运行测试时对它们进行类型检查。如果需要,可以使用 ts-jest,或者单独运行 TypeScript 编译器 tsc(或作为构建过程的一部分)。

    【讨论】:

      【解决方案4】:

      我陷入了同样的境地。由于我有一个基于 TypeScript 的私有未编译包,并且我所有的源文件和测试文件都使用了 ECMA(导入语法),所以我也遇到了以下错误。

      SyntaxError: 不能在模块外使用 import 语句

      我尝试过的解决方案。

      • 以上答案,如在jest.config.ts中使用transformtransformIgnorePatternsmoduleNameMapper
      • 按照JEST官方文档Configuration Jest#transformignorepatterns-arraystring,我用的方法一模一样,甚至参考了React Native Guide的用例。
      • 删除所有node_modules,包括缓存,并重新安装它们。
      • 使用 react-scripts 并将 jestbabel-jest 从 27 降级到 26。出现了另一个问题。

      毕竟我是从JEST官方文档中找到ECMAScript Modules的,四步完美解决了我的问题。我在此处粘贴了他们的说明,但是,您应该查看文档本身。

      1. 确保您通过传递 transform: {} 来禁用代码转换,或者以其他方式将您的转换器配置为发出 ESM 而不是默认的 CommonJS (CJS)。
      2. 使用 --experimental-vm-modules 执行节点,例如node --experimental-vm-modules node_modules/.bin/jest 或 NODE_OPTIONS=--experimental-vm-modules npx jest 等。在 Windows 上,您可以使用 cross-env 来设置环境变量。
      3. 除此之外,我们尝试遵循节点的逻辑来激活“ESM 模式”(例如查看 package.json 或 mjs 文件中的类型),请参阅他们的文档了解详细信息。
      4. 如果您想将其他文件扩展名(如 ts)视为 ESM,请使用 extensionsToTreatAsEsm 选项。

      【讨论】:

        【解决方案5】:

        您不一定需要将转换器从 babel-jest 更改为 ts-jest。

        改为:

        1. 将您的 .babelrc 重命名为 babel.config.json https://babeljs.io/docs/en/configuration#whats-your-use-case

        2. 添加 transformIgnorePatterns:

            "transformIgnorePatterns": [
              "node_modules/(?!variables/.*)"
            ]
        

        这解决了我类似的问题,无需添加额外的转换模式。 .babelrc 在您的项目中是本地的,因此它不会在 Jest 中应用于 node_modules

        【讨论】:

          【解决方案6】:

          tl;dr:tsconfig.spec.json > { "compilerOptions": { "allowJs": true } }

          这里提到的其他一切都做了吗:

          • 转换忽略模式
          • 向转换部分添加额外的模式
          • ...之后我恢复的更多内容

          然后我调试到变压器。首先想到我意识到:预配置的工作区没有记录任何内容,甚至没有记录到 ts-jest.log,没有 --verbose--debug,甚至没有警告,那本来是:

          allowJs 选项未设置为 true(文件:{{path}})时,有一个要编译的 .js 文件。要解决这个问题:

          • 如果您希望 TypeScript 处理 JS 文件,请在您的 TypeScript 配置(通常是 tsconfig.json)中将 allowJs 设置为 true
          • 如果您不希望 TypeScript 处理您的 .js 文件,请在您的 Jest 配置中更改值为 ts-jesttransform 键,使其不再匹配 .js 文件

          (见:ts-jest-transformer.ts

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-11-21
            • 2022-11-26
            • 2022-11-23
            • 2022-11-21
            • 2021-08-11
            • 2022-09-26
            相关资源
            最近更新 更多