Jest won't transform the module - SyntaxError: Cannot use import statement outside a module
Jest won't transform the module - SyntaxError: Cannot use import statement outside a module
无论我怎样尝试,我都无法摆脱这个 SyntaxError: Cannot use import statement outside a module
错误,这让我很沮丧。这里有没有人解决了这个问题?我已经阅读了一百万个 Whosebug 和 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 配置中,testPathIgnorePatterns
、transformIgnorePatterns
使用.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')
})
})
知道如何解决这个问题吗?
尽管我分别尝试过它们,但我没有一起尝试过它们(transform
和 transformIgnorePatterns
)。所以这个玩笑配置解决了我的问题:
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"transform": {
"node_modules/variables/.+\.(j|t)sx?$": "ts-jest"
},
"transformIgnorePatterns": [
"node_modules/(?!variables/.*)"
]
},
我的错误是:
- 不一起使用
transform
和 transformIgnorePatterns
。
- 并将
babel-jest
定义为转换器而不是 ts-jest
(我想当 jest 的 preset 定义为 [=17 时,这是一个问题=]。因为如果我将其更改为 babel-jest
,它会再次抛出相同的错误。):
--- "node_modules/variables/.+\.(j|t)sx?$": "babel-jest"
+++ "node_modules/variables/.+\.(j|t)sx?$": "ts-jest"
由于 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'
}
另一种解决方法是使用 ts-jest, quoted from Jest's getting started
However, there are some caveats to using TypeScript with Babel. Because TypeScript support in Babel is purely transpilation, Jest will not type-check your tests as they are run. If you want that, you can use ts-jest instead, or just run the TypeScript compiler tsc separately (or as part of your build process).
我遇到了同样的情况。由于我有一个基于TypeScript的私有未编译包,并且我所有的源文件和测试文件都应用了ECMA(导入语法),所以我也遇到了以下错误。
SyntaxError: Cannot use import statement outside a module
我试过的解决方法
- 上面的答案,比如在[=中使用transform、transformIgnorePatterns、moduleNameMapper 10=].
- 关注JEST官方文档,Configuration Jest#transformignorepatterns-arraystring, I used exactly the same method and even referred to the use case from React Native Guide.
- 删除了所有
node_modules
,包括缓存,然后重新安装。
- 使用 react-scripts 并将 jest 和 babel-jest 从 27 降级为 26 . 出现了另一个问题。
毕竟我是从JEST官方文档中找到ECMAScript Modules的,这四个步骤完美的解决了我的问题。我在这里粘贴了他们的说明,但是,您应该查看文档本身。
- 确保您通过传递 transform: {} 禁用代码转换或以其他方式配置您的转换器以发出 ESM 而不是默认的 CommonJS (CJS)。
- 使用 --experimental-vm-modules 执行节点,例如node --experimental-vm-modules node_modules/.bin/jest 或 NODE_OPTIONS=--experimental-vm-modules npx jest 等。在 Windows 上,你可以使用 cross -env 能够设置环境变量。
- 除此之外,我们尝试遵循节点激活“ESM 模式”的逻辑(例如查看 package.json 或 mjs 文件中的类型),详情请参阅他们的文档。
- 如果您想将其他文件扩展名(例如 ts)视为 ESM,请使用 extensionsToTreatAsEsm 选项。
您不一定需要将转换器从 babel-jest 更改为 ts-jest。
改为:
将您的 .babelrc
重命名为 babel.config.json
https://babeljs.io/docs/en/configuration#whats-your-use-case
添加 transformIgnorePatterns:
"transformIgnorePatterns": [
"node_modules/(?!variables/.*)"
]
这解决了我的类似问题,无需添加额外的转换模式。 .babelrc
是您项目的本地项目,因此不会应用于 Jest 中的 node_modules
。
tl;dr: tsconfig.spec.json > { "compilerOptions": { "allowJs": true } }
这里提到的所有其他内容:
- transformIgnorePatterns
- 向转换部分添加一个附加模式
- ...我后来恢复的更多
然后我调试进了transformer。首先我意识到:预配置的工作区不记录任何内容,甚至不记录到 ts-jest.log,不记录 --verbose
或 --debug
,甚至不记录警告,那本来是:
Got a .js
file to compile while allowJs
option is not set to true
(file: {{path}}). To fix this:
- if you want TypeScript to process JS files, set
allowJs
to true
in your TypeScript config (usually tsconfig.json)
- if you do not want TypeScript to process your
.js
files, in your Jest config change the transform
key which value is ts-jest
so that it does not match .js
files anymore
一个简单的解决方案是在 jest.config.js
文件中使用不同的预设。
不要使用默认 "preset": "ts-jest"
,而是尝试使用 "preset": "ts-jest/presets/js-with-ts"
等预设。基于documentation,它将:
ts-jest/presets/js-with-ts
TypeScript and JavaScript files (.ts, .tsx, .js, .jsx) will be transformed by ts-jest to CommonJS syntax.
You'll need to set allowJs to true in your tsconfig.json file.
我的问题在某种程度上有所不同,jest
会偶然发现来自 node_modules
中依赖项之一的 .js
文件 SyntaxError: Cannot use import statement outside a module
。
我必须确保 ts-jest
不会忽略(在转换时)具有麻烦依赖性的 .js
文件。
仔细阅读 about presets 后,我意识到,它让他们 'as-is' 和 preset: 'ts-jest'
。我将其更改为 preset: 'ts-jest/presets/js-with-ts'
并在 tsconfig.json
.
中设置 "allowJs": true
为了不弄乱我的项目 tsconfig.json
,我为 jest
.
准备了一个单独的项目
最后,我的jest.config.js
主要是这样的:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: "node",
globals: {
'ts-jest': {
tsconfig: '<rootDir>/test/tsconfig.json',
},
},
transformIgnorePatterns: [
"node_modules/(?!troublesome-dependency/.*)",
],
}
P.S。我不需要 transform
字段,因为预设已经在上面了。
P.P.S。我不需要介绍任何 babel
配置
无论我怎样尝试,我都无法摆脱这个 SyntaxError: Cannot use import statement outside a module
错误,这让我很沮丧。这里有没有人解决了这个问题?我已经阅读了一百万个 Whosebug 和 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 配置中,
testPathIgnorePatterns
、transformIgnorePatterns
使用
.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')
})
})
知道如何解决这个问题吗?
尽管我分别尝试过它们,但我没有一起尝试过它们(transform
和 transformIgnorePatterns
)。所以这个玩笑配置解决了我的问题:
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"transform": {
"node_modules/variables/.+\.(j|t)sx?$": "ts-jest"
},
"transformIgnorePatterns": [
"node_modules/(?!variables/.*)"
]
},
我的错误是:
- 不一起使用
transform
和transformIgnorePatterns
。 - 并将
babel-jest
定义为转换器而不是ts-jest
(我想当 jest 的 preset 定义为 [=17 时,这是一个问题=]。因为如果我将其更改为babel-jest
,它会再次抛出相同的错误。):
--- "node_modules/variables/.+\.(j|t)sx?$": "babel-jest"
+++ "node_modules/variables/.+\.(j|t)sx?$": "ts-jest"
由于 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'
}
另一种解决方法是使用 ts-jest, quoted from Jest's getting started
However, there are some caveats to using TypeScript with Babel. Because TypeScript support in Babel is purely transpilation, Jest will not type-check your tests as they are run. If you want that, you can use ts-jest instead, or just run the TypeScript compiler tsc separately (or as part of your build process).
我遇到了同样的情况。由于我有一个基于TypeScript的私有未编译包,并且我所有的源文件和测试文件都应用了ECMA(导入语法),所以我也遇到了以下错误。
SyntaxError: Cannot use import statement outside a module
我试过的解决方法
- 上面的答案,比如在[=中使用transform、transformIgnorePatterns、moduleNameMapper 10=].
- 关注JEST官方文档,Configuration Jest#transformignorepatterns-arraystring, I used exactly the same method and even referred to the use case from React Native Guide.
- 删除了所有
node_modules
,包括缓存,然后重新安装。 - 使用 react-scripts 并将 jest 和 babel-jest 从 27 降级为 26 . 出现了另一个问题。
毕竟我是从JEST官方文档中找到ECMAScript Modules的,这四个步骤完美的解决了我的问题。我在这里粘贴了他们的说明,但是,您应该查看文档本身。
- 确保您通过传递 transform: {} 禁用代码转换或以其他方式配置您的转换器以发出 ESM 而不是默认的 CommonJS (CJS)。
- 使用 --experimental-vm-modules 执行节点,例如node --experimental-vm-modules node_modules/.bin/jest 或 NODE_OPTIONS=--experimental-vm-modules npx jest 等。在 Windows 上,你可以使用 cross -env 能够设置环境变量。
- 除此之外,我们尝试遵循节点激活“ESM 模式”的逻辑(例如查看 package.json 或 mjs 文件中的类型),详情请参阅他们的文档。
- 如果您想将其他文件扩展名(例如 ts)视为 ESM,请使用 extensionsToTreatAsEsm 选项。
您不一定需要将转换器从 babel-jest 更改为 ts-jest。
改为:
将您的
.babelrc
重命名为babel.config.json
https://babeljs.io/docs/en/configuration#whats-your-use-case添加 transformIgnorePatterns:
"transformIgnorePatterns": [
"node_modules/(?!variables/.*)"
]
这解决了我的类似问题,无需添加额外的转换模式。 .babelrc
是您项目的本地项目,因此不会应用于 Jest 中的 node_modules
。
tl;dr: tsconfig.spec.json >
{ "compilerOptions": { "allowJs": true } }
这里提到的所有其他内容:
- transformIgnorePatterns
- 向转换部分添加一个附加模式
- ...我后来恢复的更多
然后我调试进了transformer。首先我意识到:预配置的工作区不记录任何内容,甚至不记录到 ts-jest.log,不记录 --verbose
或 --debug
,甚至不记录警告,那本来是:
Got a
.js
file to compile whileallowJs
option is not set totrue
(file: {{path}}). To fix this:
- if you want TypeScript to process JS files, set
allowJs
totrue
in your TypeScript config (usually tsconfig.json)- if you do not want TypeScript to process your
.js
files, in your Jest config change thetransform
key which value ists-jest
so that it does not match.js
files anymore
一个简单的解决方案是在 jest.config.js
文件中使用不同的预设。
不要使用默认 "preset": "ts-jest"
,而是尝试使用 "preset": "ts-jest/presets/js-with-ts"
等预设。基于documentation,它将:
ts-jest/presets/js-with-ts
TypeScript and JavaScript files (.ts, .tsx, .js, .jsx) will be transformed by ts-jest to CommonJS syntax. You'll need to set allowJs to true in your tsconfig.json file.
我的问题在某种程度上有所不同,jest
会偶然发现来自 node_modules
中依赖项之一的 .js
文件 SyntaxError: Cannot use import statement outside a module
。
我必须确保 ts-jest
不会忽略(在转换时)具有麻烦依赖性的 .js
文件。
仔细阅读 about presets 后,我意识到,它让他们 'as-is' 和 preset: 'ts-jest'
。我将其更改为 preset: 'ts-jest/presets/js-with-ts'
并在 tsconfig.json
.
"allowJs": true
为了不弄乱我的项目 tsconfig.json
,我为 jest
.
最后,我的jest.config.js
主要是这样的:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: "node",
globals: {
'ts-jest': {
tsconfig: '<rootDir>/test/tsconfig.json',
},
},
transformIgnorePatterns: [
"node_modules/(?!troublesome-dependency/.*)",
],
}
P.S。我不需要 transform
字段,因为预设已经在上面了。
P.P.S。我不需要介绍任何 babel
配置