使用React-native 0.56进行正确的Jest配置

时间:2018-07-09 15:43:38

标签: react-native babeljs jestjs

升级到本机0.56后,我在过去运行得很好的玩笑规格上遇到了很多babel相关错误。

我意识到,本机0.56需要babel7,这可能是相关的,但是我对babel的经验/了解不足,无法弄清我所缺少的内容。

一些错误示例:

 /xxx/spec/Bootstrap.test.js:6
import thunk from 'redux-thunk';
       ^^^^^

SyntaxError: Unexpected identifier

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)

另一个:

 import { rootReducer } from '../store';
       ^

SyntaxError: Unexpected token {

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)

我的package.json开玩笑的配置如下:

 "jest": {
"preset": "react-native",
"collectCoverage": true,
"coverageReporters": [
  "cobertura",
  "lcov"
],
"coverageDirectory": "coverage",
"globals": {
  "__TEST__": true
},
"moduleNameMapper": {
  "styled-components": "<rootDir>/node_modules/styled-components/dist/styled-components.native.cjs.js"
},
"moduleDirectories": [
  "node_modules",
  "/"
],
"transformIgnorePatterns": [
  "node_modules/(?!react-native|react-navigation)/"
],
"setupFiles": [
  "jest-localstorage-mock",
  "./node_modules/appcenter/test/AppCenterMock.js",
  "./node_modules/appcenter-analytics/test/AppCenterAnalyticsMock.js",
  "./node_modules/appcenter-crashes/test/AppCenterCrashesMock.js"
]

},

.babelrc的定义如下:

   {
  "presets": ["react-native"],
  "env": {
    "development": {
      "plugins": ["transform-class-properties"]
    },
    "test": {
      "plugins": ["transform-class-properties"]
    }
  }
}

我还具有以下依赖性:

"@babel/core": "^7.0.0-beta.52",
"babel-core": "^7.0.0-beta.52",
"babel-eslint": "~8.2.5",
"babel-plugin-module-resolver": "^3.1.1",
"babel-plugin-transform-class-properties": "~6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
"babel-preset-expo": "~4.0.0",
"babel-preset-react-native": "^5.0.1",
"babel-preset-react-native-stage-0": "^1.0.1",
"babel-preset-stage-0": "^6.24.1",

我尝试了几种方法,但是进展不大。

除了玩笑的环境外,应用程序还可以正常运行。

1 个答案:

答案 0 :(得分:0)

在0.57尚未准备就绪时,我确实要继续解决的方法的详细信息:

基本上我必须创建2个配置文件:

jest-acceptance.config(带有以下相关代码段)

 "preset": "react-native",
  "transform": {
    "^.+\\.js$": "<rootDir>/custom_b7_processor.js"
  },
  "testRegex": "(/test/.*|(\\.|/)spec)\\.js$",

jest-unit.config(带有以下相关片段)

  "preset": "react-native",
  "testRegex": "(/test/.*|(\\.|/)test)\\.js$",

custom_b7_processor是来自react-native的某种内部代码:

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 */

/* eslint-disable */

'use strict';

const {transformSync: babelTransformSync} = require('@babel/core');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
 * found when Flow v0.54 was deployed. To see the error delete this comment and
 * run Flow. */
const babelRegisterOnly = require('metro-babel-register');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
 * found when Flow v0.54 was deployed. To see the error delete this comment and
 * run Flow. */
const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction');
const generate = require('@babel/generator').default;

const nodeFiles = RegExp(
  [
    '/local-cli/',
    '/metro(?:-[^/]*)?/', // metro, metro-core, metro-source-map, metro-etc
  ].join('|'),
);
const nodeOptions = babelRegisterOnly.config([nodeFiles]);

babelRegisterOnly([]);

/* $FlowFixMe(site=react_native_oss) */
const transformer = require('metro/src/reactNativeTransformer');
module.exports = {
  process(src /*: string */, file /*: string */) {
    if (nodeFiles.test(file)) {
      // node specific transforms only
      return babelTransformSync(
        src,
        Object.assign(
          {filename: file},
          {sourceType: 'script', ...nodeOptions, ast: false},
        ),
      ).code;
    }

    const {ast} = transformer.transform({
      filename: file,
      localPath: file,
      options: {
        ast: true, // needed for open source (?) https://github.com/facebook/react-native/commit/f8d6b97140cffe8d18b2558f94570c8d1b410d5c#r28647044
        dev: true,
        inlineRequires: true,
        platform: '',
        projectRoot: '',
        retainLines: true,
        sourceType: 'unambiguous', // b7 required. detects module vs script mode
      },
      src,
      plugins: [
        [require('@babel/plugin-transform-block-scoping')],
        // the flow strip types plugin must go BEFORE class properties!
        // there'll be a test case that fails if you don't.
        [require('@babel/plugin-transform-flow-strip-types')],
        [
          require('@babel/plugin-proposal-class-properties'),
          // use `this.foo = bar` instead of `this.defineProperty('foo', ...)`
          {loose: true},
        ],
        [require('@babel/plugin-transform-computed-properties')],
        [require('@babel/plugin-transform-destructuring')],
        [require('@babel/plugin-transform-function-name')],
        [require('@babel/plugin-transform-literals')],
        [require('@babel/plugin-transform-parameters')],
        [require('@babel/plugin-transform-shorthand-properties')],
        [require('@babel/plugin-transform-react-jsx')],
        [require('@babel/plugin-transform-regenerator')],
        [require('@babel/plugin-transform-sticky-regex')],
        [require('@babel/plugin-transform-unicode-regex')],
        [
          require('@babel/plugin-transform-modules-commonjs'),
          {strict: false, allowTopLevelThis: true},
        ],
        [require('@babel/plugin-transform-classes')],
        [require('@babel/plugin-transform-arrow-functions')],
        [require('@babel/plugin-transform-spread')],
        [require('@babel/plugin-proposal-object-rest-spread')],
        [
          require('@babel/plugin-transform-template-literals'),
          {loose: true}, // dont 'a'.concat('b'), just use 'a'+'b'
        ],
        [require('@babel/plugin-transform-exponentiation-operator')],
        [require('@babel/plugin-transform-object-assign')],
        [require('@babel/plugin-transform-for-of'), {loose: true}],
        [require('@babel/plugin-transform-react-display-name')],
        [require('@babel/plugin-transform-react-jsx-source')],
      ],
    });

    return generate(
      ast,
      {
        code: true,
        comments: false,
        compact: false,
        filename: file,
        retainLines: true,
        sourceFileName: file,
        sourceMaps: true,
      },
      src,
    ).code;
  },

  getCacheKey: createCacheKeyFunction([
    __filename,
    require.resolve('metro/src/reactNativeTransformer'),
    require.resolve('@babel/core/package.json'),
  ]),
};

在我的.babelrc中,我必须包括以下内容:

“预设”:[“ ./ node_modules / babel-preset-react-native-b6”],

这指向我由React-native在0.56-使用的babel预设构成的叉子。

https://github.com/lhrolim/babel-preset-react-native

在我的package.json中,我遵循了babel依赖项

"babel-preset-react-native": "~5.0.2",
"babel-preset-react-native-b6": "github:lhrolim/babel-preset-react-native",

我当时使用的测试脚本:

"test": "npm run test-acc && npm run test-unit",
"test-acc": "jest --config=jest_acceptance-config.json",
"test-unit": "jest --config=jest_unit-config.json",

我相信这里和那里可能会有一些冗余,但这对我有用。