如何阻止我的 React Native 测试对 Node Modules 中的 Flow 类型进行轰炸?

Wil*_*ill 15 javascript meteor jestjs babeljs react-native

我正在尝试对现有的 React Native 项目进行测试。当我使用 Jest 运行测试时,测试会出现以下错误:

Test suite failed to run

   ...etc/__app__/node_modules/react-native/Libraries/polyfills/error-guard.js:14
    type ErrorHandler = (error: mixed, isFatal: boolean) => void;
         ^^^^^^^^^^^^

    SyntaxError: Unexpected identifier
      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
      at Object.<anonymous> (node_modules/react-native/jest/setup.js:16:6)

Run Code Online (Sandbox Code Playgroud)

意外的标识符如下:

 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow strict
 * @polyfill
 */

let _inGuard = 0;

type ErrorHandler = (error: mixed, isFatal: boolean) => void;
Run Code Online (Sandbox Code Playgroud)

我推测这个问题与React 和 Flow 预设的分离有关。

node_modules 中的代码包含 Flowtype 语法。我的 Babel 配置适用于我自己的代码,但不适用于 node_modules 中的文件。

我的 babel.config.js:

  presets: ['module:metro-react-native-babel-preset', "@babel/preset-flow", "@babel/plugin-transform-flow-strip-types"],
};
Run Code Online (Sandbox Code Playgroud)

我的 Jest package.json:

"jest": {
    "verbose": true,
    "preset": "react-native",
    "transformIgnorePatterns": [
      "node_modules/(?!react-native|@tableflip/react-native-navbar)",
      "/node_modules/(?!@babel/runtime)",
      "node_modules/(?!(react-native|__app__|react-native-button)/)",
      "/node_modules/(?!react-native)/.+"

    ],
    "setupFilesAfterEnv": [
      "<rootDir>/node_modules/riteway-jest/src/riteway-jest.js"
    ]
  },
Run Code Online (Sandbox Code Playgroud)

如何阻止我的测试轰炸节点模块中的 Flow 类型?

编辑:完整的 package.JSON

{
  "name": "ReactNativeTest",

  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "start:ios": "react-native run-ios && react-native log-ios",
    "start:android": "react-native run-android && react-native log-android",
    "start:ios:debug": "react-native run-ios --simulator=\"iPhone X\" & open \"rndebugger://set-debugger-loc?host=localhost&port=8081\"",
    "start:android:debug": "react-native run-android & open \"rndebugger://set-debugger-loc?host=localhost&port=8081\"",
    "start:debug": "open \"rndebugger://set-debugger-loc?host=localhost&port=8081\"",
    "lint": "standard",
    "test": "jest"
  },
  "dependencies": {
    "@babel/preset-env": "^7.8.4",
    "@babel/runtime": "7.0.0-beta.55",
    "@expo/react-native-action-sheet": "3.4.0",
    "@react-native-community/async-storage": "1.6.3",
    "@react-native-community/netinfo": "4.6.1",
    "@react-native-community/viewpager": "3.3.0",
    "babel-core": "^7.0.0-bridge.0",
    "babel-preset-react-app": "^7.0.0",
    "ejson": "2.2.0",
    "lodash-es": "4.17.15",
    "lodash.isstring": "4.0.1",
    "markdown-it": "10.0.0",
    "meteor-standalone-random": "1.0.67",
    "moment": "2.24.0",
    "prop-types": "15.7.2",
    "react": "16.12.0",
    "react-native": "0.61.5",
    "react-native-calendar-events": "1.7.3",
    "react-native-config": "0.11.7",
    "react-native-dismiss-keyboard": "1.0.0",
    "react-native-firebase": "5.6.0",
    "react-native-hyperlink": "0.0.16",
    "react-native-image-picker": "1.1.0",
    "react-native-iphone-x-helper": "1.2.1",
    "react-native-joi": "0.0.5",
    "react-native-keyboard-aware-scroll-view": "0.9.1",
    "react-native-keyboard-spacer": "0.4.1",
    "react-native-maps": "0.26.1",
    "react-native-onesignal": "3.5.0",
    "react-native-scrollable-tab-view": "1.0.0",
    "react-native-select-multiple": "2.1.0",
    "react-native-side-menu": "1.1.3",
    "react-native-swiper": "1.5.14",
    "react-native-thumbnail-video": "0.1.2",
    "react-native-touch-id": "4.4.1",
    "react-native-uploadcare-image": "2.0.0",
    "react-native-video": "5.0.2",
    "react-native-webview": "7.5.2",
    "react-redux": "7.1.3",
    "reduce-reducers": "1.0.4",
    "redux": "4.0.4",
    "redux-devtools-extension": "2.13.8",
    "redux-localstorage": "github:tableflip/redux-localstorage#fix-buffer-main-src",
    "redux-localstorage-filter": "0.1.1",
    "redux-thunk": "2.3.0",
    "url": "0.11.0",
    "uuid": "3.3.3"
  },
  "jest": {
    "verbose": true,
    "preset": "react-native",
    "transformIgnorePatterns": [
      "<rootDir>/node_modules/(?!@babel/runtime)",
      "<rootDir>node_modules/(?!(react-native|__app__|react-native-button)/)",
      "/node_modules/(?!react-native)/.+",
      "/node_modules/"
    ],
    "setupFilesAfterEnv": [
      "<rootDir>/src/riteway-jest.js"
    ]
  },
  "devDependencies": {
    "@babel/core": "^7.7.4",
    "@babel/plugin-transform-flow-strip-types": "^7.8.3",
    "@babel/plugin-transform-runtime": "^7.8.3",
    "@babel/preset-flow": "^7.8.3",
    "babel-eslint": "10.0.3",
    "babel-jest": "^24.9.0",
    "babel-plugin-import-rename": "1.0.1",
    "jest": "24.9.0",
    "jetifier": "1.6.4",
    "metro-react-native-babel-preset": "0.57.0",
    "react-native-config-node": "0.0.2",
    "react-test-renderer": "16.12.0",
    "redux-mock-store": "1.5.3",
    "riteway-jest": "^2.0.2",
    "standard": "14.3.1"
  },
  "standard": {
    "parser": "babel-eslint",
    "globals": [
      "fetch",
      "FormData",
      "it",
      "expect"
    ]
  },
  "transform": {
    "^.+\\.[t|j]sx?$": "babel-jest"
  }
}

Run Code Online (Sandbox Code Playgroud)

小智 18

就我而言,我需要将带有“@”的 @react-native 添加到 transformIgnorePatterns 中,如下所示:

"transformIgnorePatterns": [
  "node_modules/(?!(@react-native|react-native)/)"
]
Run Code Online (Sandbox Code Playgroud)


Sha*_*dra 8

首先,我们需要了解根本原因是什么。

SyntaxError: Unexpected identifier
Run Code Online (Sandbox Code Playgroud)

基本上,这些类型的错误是由于您的 jest 配置而发生的。如果您被指示转换 node_modules 内的所有库,它将引发这些类型的错误。因此,请继续检查 package.json jest 配置中的以下语句。

transformIgnorePatterns
Run Code Online (Sandbox Code Playgroud)

上面用于添加一些转换忽略模式,它将具有默认的正则表达式模式=>["/node_modules/", "\\.pnp\\.[^\\\/]+$"]

以下来自官方笑话文档

有时(特别是在 React Native 或 TypeScript 项目中),第 3 方模块会以未转译的形式发布。由于默认情况下,node_modules 内的所有文件都不会被转换,因此 Jest 将无法理解这些模块中的代码,从而导致语法错误。为了克服这个问题,您可以使用transformIgnorePatterns来允许转译此类模块。您将在 React Native Guide 中找到此用例的一个很好的示例。

因此,尝试按照 @Pavot 的指示在其中一个答案中添加以下内容将有助于修复。但如果是其他库发生的类似问题,您可以尝试将其添加到转换忽略列表中,看看它是否有效。

"transformIgnorePatterns": [
  "node_modules/(?!(@react-native|react-native)/)"
]
Run Code Online (Sandbox Code Playgroud)


Gha*_*Haq 4

package.json中的transformIgnorePatterns存在问题。只需按照此模式将模块添加到黑名单即可,而不是在其中添加项目数量。

"transformIgnorePatterns": [
      "node_modules/(?!MODULE_NAME_1|MODULE_NAME_2)/"
    ], 
Run Code Online (Sandbox Code Playgroud)

从您的错误来看,我们需要将react-native添加到transformIgnorePatterns。实际上,我们需要将所有会抛出错误的模块添加到黑名单中,因为大多数模块都不是完全用 JS 编写的。

最后,就我而言,package.json中的笑话

"jest": {
    "preset": "react-native",
    "transformIgnorePatterns": [
      "node_modules/(?!react-native-payfort-sdk|react-native)/"
    ],
    "globals": {
      "__DEV__": true
    },
    "testEnvironment": "node"
  }
Run Code Online (Sandbox Code Playgroud)

这对我有用,希望这也会对您有所帮助。

  • 这并没有修复 React Native 0.63 的错误,而且笑话“react-native”预设已经包含了 react-native。 (3认同)