Comment utiliser jest avec webpack?

j'utilise webpack pour développer un composant React. Voici une version simplifiée de celui-ci:

'use strict';

require('./MyComponent.less');

var React = require('react');

var MyComponent = React.createClass({
  render() {
    return (
      <div className="my-component">
        Hello World
      </div>
    );
  }
});

module.exports = MyComponent;

maintenant, je voudrais tester ce composant en utilisant rire. Voici les bits de mon package.json:

"scripts": {
  "test": "jest"
},
"jest": {
  "rootDir": ".",
  "testDirectoryName": "tests",
  "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
  "unmockedModulePathPatterns": [
    "react"
  ]
}

Lors de l'exécution npm test, j'obtiens l'erreur suivante:

SyntaxError: /Users/mishamoroshko/réagir-composant/src/tests/Moncomposant.js: /Users/mishamoroshko/réagir-composant/src/Moncomposant.js: /Utilisateurs/mishamoroshko/réagir-composant/src/Moncomposant.moins: jeton inattendu illégal

Ressemble webpack besoins de processus require('./MyComponent.less') avant que jest puisse lancer le test.

je me demande si j'ai besoin d'utiliser quelque chose comme jest-webpack. Si oui, est-il un moyen de spécifier plusieurs scriptPreprocessor s? (notez que j'ai déjà utiliser babel-jest)

46
demandé sur Cihan Keser 2015-03-05 07:54:50

11 réponses

j'ai fini avec la suite de hack:

// package.json

"jest": {
  "scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
  ...
}


// jest-script-preprocessor.js
var babelJest = require("babel-jest");

module.exports = {
  process: function(src, filename) {
    return babelJest.process(src, filename)
      .replace(/^require.*\.less.*;$/gm, '');
  }
};

mais, je me demande toujours quelle est la bonne solution à ce problème.

19
répondu Misha Moroshko 2015-03-05 09:22:32

LA solution la plus propre que j'ai trouvée pour ignorer un module requis est d'utiliser le moduleNameMapper config (fonctionne sur la dernière version 0.9.2)

La documentation est difficile à suivre. J'espère que la suite va nous aider.

ajouter la touche moduleNameMapper à vos paquets.JSON config. La clé d'un élément doit être un regex de la chaîne requise. Exemple avec".moins fichiers:

"moduleNameMapper": { "^.*[.](less|LESS)$": "EmptyModule" },

Ajouter un EmptyModule.js à la racine de votre dossier:

/**
 * @providesModule EmptyModule
 */
module.exports = '';

le commentaire est important puisque le moduleNameMapper utilise EmptyModule comme alias de ce module (en savoir plus sur providesModule).

maintenant chaque référence require qui correspond à la regex sera remplacée par une chaîne vide.

si vous utilisez la configuration moduleFileExtensions avec un fichier 'js', alors assurez-vous d'ajouter L'EmptyModule à votre'modulepathpatterns'.

Voici la configuration jest J'ai fini avec:

"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"moduleFileExtensions": ["js", "json","jsx" ],
"moduleNameMapper": {
  "^.*[.](jpg|JPG|gif|GIF|png|PNG|less|LESS|css|CSS)$": "EmptyModule"
},
"preprocessorIgnorePatterns": [ "/node_modules/" ],
"unmockedModulePathPatterns": [
  "<rootDir>/node_modules/react",
  "<rootDir>/node_modules/react-dom",
  "<rootDir>/node_modules/react-addons-test-utils",
  "<rootDir>/EmptyModule.js"
]
}
19
répondu ZahiC 2016-03-21 17:57:33

je viens de découvrir que c'est encore plus simple avec Jest's moduleNameMapper configuration.

// package.json

"jest": {
    "moduleNameMapper": {
      "^.+\.scss$": "<rootDir>/scripts/mocks/style-mock.js"
    }
}

// style-mock.js

module.exports = {};

plus de détails à Jest tutoriel.

9
répondu Tien Do 2018-04-25 18:27:27

j'ai récemment publié Jestpack qui pourrait aider. Il construit d'abord vos fichiers de test avec Webpack ainsi toute résolution de module personnalisé / chargeurs / plugins etc. juste travailler et vous vous retrouvez avec JavaScript. Il fournit ensuite un chargeur de module personnalisé pour Jest qui comprend l'exécution du module webpack.

4
répondu riscarrott 2015-10-20 12:09:18

Jest docs:

// in terminal, add new dependency: identity-obj-proxy
npm install --save-dev identity-obj-proxy

// package.json (for CSS Modules)
{
  "jest": {
    "moduleNameMapper": {
      "\.(css|less)$": "identity-obj-proxy"
    }
  }
}

L'extrait ci-dessus permettra d'acheminer tous .less les fichiers de la nouvelle dépendance identity-obj-proxy, qui renvoie une chaîne avec le nom de classe lorsqu'elle est invoquée, par exemple 'styleName'styles.styleName.

3
répondu tbraun 2017-08-29 21:19:43

je pense que moins hacky solution serait pour envelopper votre préprocesseur dans une condition sur le nom de fichier correspondant à un fichier javascript:

if (filename.match(/\.jsx?$/)) {
    return babelJest.process(src, filename);
} else {
    return '';
}

cela fonctionne même si vous ne définissez pas explicitement l'extension dans la ligne require et n'avez pas besoin de substitution regex sur la source.

2
répondu Krustal 2015-10-17 19:27:07

j'ai connu le même problème avec un tel modèle

import React, { PropTypes, Component } from 'react';
import styles from './ContactPage.css';
import withStyles from '../../decorators/withStyles';

@withStyles(styles)
class ContactPage extends Component {

voir l'exemple à https://github.com/kriasoft/react-starter-kit/blob/9204f2661ebee15dcb0b2feed4ae1d2137a8d213/src/components/ContactPage/ContactPage.js#L4-L7

Pour l'exécution de Plaisanterie, je dispose de 2 problèmes:

  • importation de .css
  • application de décorateur @withStyles (TypeError: <...> (0 , _appDecoratorsWithStyles2.default)(...) is not a function)

Premier a été résolu en se moquant .css lui - même dans le script préprocesseur.

Second a été résolu en excluant les décorateurs de l'automockage en utilisant unmockedModulePathPatterns

module.exports = {
  process: function (src, filename) {

    ...

    if (filename.match(/\.css$/)) src = '';

    ...

    babel.transform(src, ...
  }
}

exemple basé sur https://github.com/babel/babel-jest/blob/77a24a71ae2291af64f51a237b2a9146fa38b136/index.js

Note aussi: lorsque vous travaillez avec le préprocesseur jest, vous devez nettoyer le cache:

$ rm node_modules/jest-cli/.haste_cache -r
1
répondu x'ES 2015-11-08 00:04:00

en m'inspirant de la réponse de Misha, j'ai créé un paquet NPM qui résout ce problème tout en traitant quelques autres scénarios que j'ai rencontrés:

webpack-babel-jest

espérons que cela puisse sauver la prochaine personne quelques heures.

0
répondu Carlos Atencio 2015-08-14 20:56:55

si vous utilisez babel, vous pouvez retirer les importations indésirables pendant la transformation babel en utilisant quelque chose comme https://github.com/Shyp/babel-plugin-import-noop et la configuration de votre .babelrctest env pour utiliser le plugin, comme suit:

{
  "env": {
    "development": {
      ...
    },
    "test": {
      "presets": [ ... ],
      "plugins": [
        ["import-noop", {
          "extensions": ["scss", "css"]
        }]
      ]
    }
  }
}
0
répondu Tarrence 2016-11-10 19:09:58

Webpack est un excellent outil, mais je n'ai pas besoin de tester son comportement avec mes tests de l'unité Jest, et ajouter une construction de webpack avant d'exécuter les tests de l'unité ne va que ralentir le processus. Le texte du livre de réponse est de simuler des dépendances sans code en utilisant le "moduleNameMapper" option

https://facebook.github.io/jest/docs/webpack.html#handling-static-assets

0
répondu Samjones 2017-04-27 18:39:15

nous avons eu un problème similaire avec les fichiers CSS. Comme vous l'avez mentionné avant jest-webpack résout ce problème très bien. Vous n'aurez pas à vous moquer ou à utiliser de mappeurs de modules non plus. Pour nous, nous avons remplacé notre mnp commande test de jestjest-webpack et il a travaillé.

0
répondu Joseph Fehrman 2018-02-14 18:02:24