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
)
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.
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"
]
}
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.
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.
// 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
.
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.
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
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:
espérons que cela puisse sauver la prochaine personne quelques heures.
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 .babelrc
test
env pour utiliser le plugin, comme suit:
{
"env": {
"development": {
...
},
"test": {
"presets": [ ... ],
"plugins": [
["import-noop", {
"extensions": ["scss", "css"]
}]
]
}
}
}
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
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 jest
jest-webpack
et il a travaillé.