3 votes

Configuration Jest appropriée avec React-native 0.56

Après la mise à niveau vers react-native 0.56, je rencontre des tonnes d'erreurs liées à Babel sur les spécifications jest qui fonctionnaient parfaitement auparavant.

Je me rends compte que react-native 0.56 nécessite babel7 et que c'est probablement lié mais je n'ai pas assez d'expérience/compréhension en babel pour comprendre ce qui me manque.

Quelques exemples d'erreurs :

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

SyntaxError: Identifiant inattendu

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

une autre :

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

SyntaxError: Jeton inattendu {

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

Ma configuration jest du package.json est la suivante :

 "jest": {
"preset": "react-native",
"collectCoverage": true,
"coverageReporters": [
  "cobertura",
  "lcov"
],
"coverageDirectory": "coverage",
"globals": {
  "__TEST__": true
},
"moduleNameMapper": {
  "styled-components": "/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 est défini comme suit :

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

J'ai également les devdependencies suivants :

"@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",

J'ai essayé plusieurs approches mais je n'ai pas pu avancer beaucoup.

En dehors de l'environnement jest, l'application fonctionne bien.

0voto

Détails du contournement que j'ai fait pour avancer, alors que la version 0.57 n'était pas prête:

Essentiellement, j'ai dû créer 2 fichiers de configuration:

jest-acceptance.config (avec les extraits pertinents suivants)

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

jest-unit.config (avec les extraits pertinents suivants)

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

Ce custom_b7_processor est une sorte de code interne de react-native:

/**
 * Droit d'auteur (c) 2015-présent, Facebook, Inc.
 *
 * Ce code source est sous licence MIT, disponible dans le fichier
 * LICENSE à la racine de ce répertoire.
 *
 * @format
 * @flow
 */

/* eslint-disable */

'use strict';

const {transformSync: babelTransformSync} = require('@babel/core');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) Ce commentaire supprime une erreur
 * trouvée lorsque Flow v0.54 a été déployé. Pour voir l'erreur, supprimez ce commentaire et
 * exécutez Flow. */
const babelRegisterOnly = require('metro-babel-register');
/* $FlowFixMe(>=0.54.0 site=react_native_oss) Ce commentaire supprime une erreur
 * trouvée lorsque Flow v0.54 a été déployé. Pour voir l'erreur, supprimez ce commentaire et
 * exécutez 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)) {
      // transformations spécifiques à node seulement
      return babelTransformSync(
        src,
        Object.assign(
          {filename: file},
          {sourceType: 'script', ...nodeOptions, ast: false},
        ),
      ).code;
    }

    const {ast} = transformer.transform({
      filename: file,
      localPath: file,
      options: {
        ast: true, // nécessaire pour l'open source (?) https://github.com/facebook/react-native/commit/f8d6b97140cffe8d18b2558f94570c8d1b410d5c#r28647044
        dev: true,
        inlineRequires: true,
        platform: '',
        projectRoot: '',
        retainLines: true,
        sourceType: 'unambiguous', // b7 requis. détecte le mode module vs script
      },
      src,
      plugins: [
        [require('@babel/plugin-transform-block-scoping')],
        // le plugin de suppression de types de flow doit aller AVANT les propriétés de classe!
        // il y aura un cas de test qui échoue si vous ne le faites pas.
        [require('@babel/plugin-transform-flow-strip-types')],
        [
          require('@babel/plugin-proposal-class-properties'),
          // utiliser `this.foo = bar` au lieu de `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}, // ne pas 'a'.concat('b'), simplement utiliser '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'),
  ]),
};

Dans mon .babelrc, j'ai dû inclure ce qui suit:

"presets": ["./node_modules/babel-preset-react-native-b6"],

Cela pointe vers un fork que j'ai fait du preset babel que React-native utilisait en version 0.56-

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

Dans mon package.json, j'avais les dépendances babel suivantes

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

Les scripts de test que j'utilisais à l'époque:

"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",

Je pense qu'il peut y avoir quelques redondances ici et là, mais c'est ce qui a fonctionné pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X