使用 Jest 和 @testing-library/react-native 测试 React Native 项目时出现“SyntaxError: Cannot use import stateme
Posted
技术标签:
【中文标题】使用 Jest 和 @testing-library/react-native 测试 React Native 项目时出现“SyntaxError: Cannot use import statement outside a module”错误?【英文标题】:"SyntaxError: Cannot use import statement outside a module" error while testing React Native project with Jest and @testing-library/react-native? 【发布时间】:2021-06-03 15:01:42 【问题描述】:我每次运行npm test
时都会遇到错误:
FAIL ./App.test.js
● 测试套件无法运行
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain javascript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/bestes/Desktop/react-native-training/node_modules/react-native-status-bar-height/index.js:1
("Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest)import Dimensions, Platform, StatusBar from 'react-native';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
at Object.<anonymous> (node_modules/react-native-elements/src/config/index.js:1:1)
我的测试:
import 'react-native';
import React from 'react';
import render from '@/../testing/test-utils'
import App from './App'
test('should render app component', () =>
const result = render(<App />)
expect(result).toMatchSnapshot()
)
我的 test-utils.js 文件:
import React from 'react'
import render from '@testing-library/react-native'
import store from '@/bootstrap/redux'
import Provider from 'react-redux'
const AllTheProviders = ( children ) =>
return (
<Provider store=store>
children
</Provider>
)
const customRender = (ui, options) =>
render(ui, wrapper: AllTheProviders, ...options )
// re-export everything
export * from '@testing-library/react-native'
// override render method
export customRender as render
我的 package.json 文件:
"name": "ReactNativeTraining",
"version": "0.0.1",
"private": true,
"scripts":
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
,
"dependencies":
"@react-native-community/geolocation": "2.0.2",
"@react-native-community/masked-view": "0.1.10",
"@react-native-picker/picker": "1.9.10",
"@reduxjs/toolkit": "1.5.0",
"axios": "0.21.1",
"dayjs": "1.10.4",
"lodash": "4.17.20",
"react": "16.13.1",
"react-native": "0.63.2",
"react-native-config": "1.4.2",
"react-native-elements": "3.0.0-alpha.1",
"react-native-geocoding": "0.5.0",
"react-native-gesture-handler": "1.9.0",
"react-native-permissions": "3.0.0",
"react-native-picker-select": "8.0.4",
"react-native-reanimated": "1.13.2",
"react-native-safe-area-context": "3.1.9",
"react-native-screens": "2.17.0",
"react-native-size-matters": "0.4.0",
"react-native-vector-icons": "8.0.0",
"react-navigation": "4.0.2",
"react-navigation-stack": "1.5.4",
"react-navigation-tabs": "2.4.1",
"react-redux": "7.2.2"
,
"devDependencies":
"@babel/core": "7.12.10",
"@babel/runtime": "7.12.5",
"@react-native-community/eslint-config": "2.0.0",
"@testing-library/jest-native": "4.0.1",
"@testing-library/react-native": "7.2.0",
"babel-jest": "^26.6.3",
"babel-plugin-module-resolver": "4.0.0",
"eslint": "7.18.0",
"jest": "26.6.3",
"metro-react-native-babel-preset": "0.64.0",
"react-test-renderer": "16.13.1"
,
"type": "module",
"jest":
"verbose": true,
"preset": "react-native",
"setupFilesAfterEnv": ["@testing-library/jest-native/extend-expect"],
"transformIgnorePatterns": [
"node_modules/(?!(react-native",
"@react-native-community/geolocation",
"@react-native-community/masked-view",
"|@react-native-picker/picker",
"|@reduxjs/toolkit",
"|axios",
"|dayjs",
"|lodash",
"|react",
"|react-native",
"|react-native-config",
"|react-native-elements",
"|react-native-geocoding",
"|react-native-gesture-handler",
"|react-native-permissions",
"|react-native-picker-select",
"|react-native-reanimated",
"|react-native-safe-area-context",
"|react-native-screens",
"|react-native-size-matters",
"|react-native-vector-icons",
"|react-navigation",
"|react-navigation-stack",
"|react-navigation-tabs",
"|react-redux",
")/)"
]
我的 babel.config.js 文件:
module.exports = function (api)
api.cache(true)
const presets = [
'module:metro-react-native-babel-preset'
]
const plugins = [
[
'module-resolver',
'root': ['./src/'],
'extensions': ['.js', '.ios.js', '.android.js'],
'alias':
'@': './src/'
]
]
return
presets,
plugins
我尝试过的: 将 "type": "module" 添加到我的根级别 package.json 文件中,它修复了与导出类似的错误, 将转换忽略模式添加到 package.json 文件中的 Jest 键。 我将所有依赖项都添加到了 transformIgnorePatterns 中,因为它不断在每个依赖项上抛出错误,直到我添加了所有依赖项,现在它在 react-native 模块导入时抛出。
【问题讨论】:
我要补充一点,这似乎只是在尝试导入 App 组件时出现的问题。我在导入单个组件时没有看到错误。 错误似乎来自react-native-status-bar-height
模块。那是从哪里来的?您是否尝试将其包含在您的 transformIgnorePatterns
中?
【参考方案1】:
[已解决]为我工作 在下面安装
npm install --save-dev @babel/core
npm install --save-dev @babel/preset-env
之后在根目录下创建“babel.config.js”文件,内容如下
module.exports =
presets: ['@babel/preset-env', '@babel/preset-react'],
env:
test:
plugins: ["@babel/plugin-transform-runtime"]
;
【讨论】:
它的 npm install --save-dev @babel/preset-env 而不是 npm install --save-dev @babel/present-env 请更新 感谢您的更新..@MuhammadOwaisChaudhary 它不能解决 react native 项目的问题。从 0.63.3 升级到 0.66.3 突然使一些测试因这个奇怪的错误而中断。【参考方案2】:“Jest 附带对 ECMAScript 模块 (ESM) 的实验性支持” - ECMAScript Modules
在 package.json
中添加您的 test
脚本,并使用 Node 实验功能:--experimental-vm-modules
这样你就不需要 babel 或其他依赖了。
例子:
"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node' jest"
如果您收到此错误:zsh: command not found: jest
,请尝试使用 node
传递 jest.js
,如下所示:
"test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node --trace-warnings' node node_modules/jest/bin/jest.js --detectOpenHandles"
与此类似:https://***.com/a/70199545/5078874
【讨论】:
以上是关于使用 Jest 和 @testing-library/react-native 测试 React Native 项目时出现“SyntaxError: Cannot use import stateme的主要内容,如果未能解决你的问题,请参考以下文章
使用 React、Typescript 和 ES6 进行 Jest 测试
使用 jest 和 vue 抛出 SyntaxError: Unexpected identifier error for import
React Redux:使用 Enzyme/Jest 测试 mapStateToProps 和 mapDispatchToProps