在使用Jest和@testing-library/react-native测试React Native项目时出现"SyntaxError: Cannot use import statement outside a module"错误?

9

每次运行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
  }
}

我尝试的方法: 在我的根级package.json文件中添加“type”:“module”,这解决了导出的类似错误, 在package.json文件的Jest键中添加Transform Ignore Patterns。 我已将所有依赖项都添加到transformIgnorePatterns中,因为它持续在每个依赖项上抛出错误,直到我添加所有依赖项,现在它在导入react-native模块时抛出错误。

我要补充的是,当尝试导入App组件时,似乎只会出现这个问题。当我导入单个组件时,我没有看到错误。 - Ben Estes
错误似乎来自于 react-native-status-bar-height 模块。它是从哪里来的?你尝试将其包含在你的 transformIgnorePatterns 中了吗? - juliomalves
1个回答

2

[已解决] 适用于我 安装如下

npm install --save-dev @babel/core @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。 - Muhammad Owais Chaudhary
谢谢更新..@MuhammadOwaisChaudhary - Thilina Chamika
5
它并不能解决React Native项目的问题。从0.63.3升级到0.66.3后,一些测试突然出现了奇怪的错误。 - philk
2
@philk 我在 GitHub 上找到了一个关于这个问题的讨论。那里提到的修复方法适用于 React Native 0.64.0+。我在从 0.63.4 升级到 0.66.4 后测试了它,确实有帮助。 https://github.com/facebook/react-native/issues/31190#issuecomment-822586986 - theme_an

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接