开玩笑不会转换模块-SyntaxError:无法在模块外部使用import语句

时间:2020-05-13 17:41:11

标签: typescript jestjs babel-jest ts-jest

无论我尝试了什么,我都无法摆脱这个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 | 

我试图解决的问题(没有奏效):

  • 使用env中的babel.config设置: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')
  })
})

关于如何解决此问题的任何想法?

5 个答案:

答案 0 :(得分:4)

虽然我已经分别尝试了它们,但我没有一起尝试(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(我将笑话的预设定义为ts-jest时,这是一个问题。因为如果我将其更改为babel-jest,它再次引发相同的错误。):
--- "node_modules/variables/.+\\.(j|t)sx?$": "babel-jest"
+++ "node_modules/variables/.+\\.(j|t)sx?$": "ts-jest"

答案 1 :(得分:0)

由于jest无法与esmodule良好配合,因此您需要在jest.config.js中添加这些配置,以告知Jest改用commonJS构建

{{1}}

答案 2 :(得分:0)

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

<块引用>

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

答案 3 :(得分:0)

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

<块引用>

语法错误:不能在模块外使用导入语句

我尝试过的解决方案。

  • 以上答案,例如在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 选项。

答案 4 :(得分:0)

您不一定需要将转换器从 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