reactjs - change - imagenes en react
¿Cómo usar broma con webpack? (11)
Acabo de descubrir que es aún más simple con la configuración moduleNameMapper
de Jest.
// package.json
"jest": {
"moduleNameMapper": {
"^.+//.scss$": "<rootDir>/scripts/mocks/style-mock.js"
}
}
// style-mock.js
module.exports = {};
Más detalles en la página de tutorial de Jest.
Uso webpack para desarrollar un componente React. Aquí hay una versión simple de esto:
''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;
Ahora, me gustaría probar este componente usando jest . Aquí está el bit relevante de mi package.json
. package.json
:
"scripts": {
"test": "jest"
},
"jest": {
"rootDir": ".",
"testDirectoryName": "tests",
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"unmockedModulePathPatterns": [
"react"
]
}
Cuando npm test
, npm test
el siguiente error:
SyntaxError: /Users/mishamoroshko/react-component/src/tests/MyComponent.js: /Users/mishamoroshko/react-component/src/MyComponent.js: /Users/mishamoroshko/react-component/src/MyComponent.less: inesperado token ILEGAL
Parece que el paquete web necesita procesar require(''./MyComponent.less'')
antes de que jest pueda ejecutar la prueba.
Me pregunto si necesito usar algo como jest-webpack . En caso afirmativo, ¿hay alguna manera de especificar varios scriptPreprocessor
s? (Tenga en cuenta que ya uso babel-jest
)
Creo que una solución menos hacky sería envolver su preprocesador en un condicional en el nombre de archivo que coincida con un archivo de JavaScript:
if (filename.match(//.jsx?$/)) {
return babelJest.process(src, filename);
} else {
return '''';
}
Esto funciona incluso si no establece explícitamente la extensión en la línea requerida y no requiere una sustitución de expresiones regulares en el origen.
De 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"
}
}
}
El fragmento de arriba encaminará todos los archivos .less
a la nueva dependencia identity-obj-proxy
, que devolverá una cadena con el nombre de clase cuando se invoque, por ejemplo, ''styleName''
para styles.styleName
.
He experimentado un problema similar con ese patrón
import React, { PropTypes, Component } from ''react'';
import styles from ''./ContactPage.css'';
import withStyles from ''../../decorators/withStyles'';
@withStyles(styles)
class ContactPage extends Component {
Para ejecutar Jest I tiene 2 problemas:
- importación de
.css
- aplicar el decorador
@withStyles
(TypeError: <...> (0 , _appDecoratorsWithStyles2.default)(...) is not a function
)
El primero fue resuelto burlándose de .css
en sí mismo en el preprocesador de scripts.
El segundo se resolvió excluyendo a los decoradores del automobilismo usando unmockedModulePathPatterns
module.exports = {
process: function (src, filename) {
...
if (filename.match(//.css$/)) src = '''';
...
babel.transform(src, ...
}
}
ejemplo basado en https://github.com/babel/babel-jest/blob/77a24a71ae2291af64f51a237b2a9146fa38b136/index.js
Tenga en cuenta también que cuando trabaje con el preprocesador de broma, debe limpiar el caché:
$ rm node_modules/jest-cli/.haste_cache -r
Inspirándome en la respuesta de Misha, creé un paquete de NPM que resuelve este problema y también manejé algunos escenarios más que encontré:
Con suerte, esto puede salvar a la siguiente persona unas pocas horas.
La solución más limpia que encontré para ignorar un módulo requerido es usar el moduleNameMapper config (funciona en la última versión 0.9.2)
La documentación es difícil de seguir. Espero que lo siguiente ayude.
Añada la clave moduleNameMapper a su configuración de packages.json. La clave para un artículo debe ser una expresión regular de la cadena requerida. Ejemplo con archivos ''.less'':
"moduleNameMapper": { "^.*[.](less|LESS)$": "EmptyModule" },
Agregue un EmptyModule.js a su carpeta raíz:
/**
* @providesModule EmptyModule
*/
module.exports = '''';
El comentario es importante ya que moduleNameMapper utiliza EmptyModule como alias para este módulo ( lea más sobre provideModule).
Ahora cada referencia requerida que coincida con la expresión regular se reemplazará con una cadena vacía.
Si usa la configuración moduleFileExtensions con un archivo ''js'', asegúrese de que también agrega el EmptyModule a su ''unmockedModulePathPatterns''.
Aquí está la configuración de broma con la que terminé:
"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"
]
}
Recientemente Jestpack que podría ser útil. Primero construye sus archivos de prueba con Webpack para que cualquier resolución / cargadores / plugins de módulos personalizados, etc. solo funcione y termine con JavaScript. A continuación, proporciona un cargador de módulos personalizado para Jest, que comprende el tiempo de ejecución del módulo Webpack.
Si está utilizando babel, puede eliminar las importaciones no deseadas durante la transformación de babel usando algo como https://github.com/Shyp/babel-plugin-import-noop y configurando su .babelrc
test
.babelrc
para usar el complemento, como tal :
{
"env": {
"development": {
...
},
"test": {
"presets": [ ... ],
"plugins": [
["import-noop", {
"extensions": ["scss", "css"]
}]
]
}
}
}
Terminé con el siguiente truco:
// 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, '''');
}
};
Pero, todavía me pregunto cuál es la solución correcta para este problema.
Tuvimos un problema similar con los archivos CSS. Como mencionaste antes, jest-webpack soluciona bien este problema. Tampoco tendrás que burlarte o usar ningún mapeador de módulos. Para nosotros reemplazamos nuestro comando de prueba npm de jest
a jest-webpack
y simplemente funcionó.
Webpack es una gran herramienta, pero no necesito probar su comportamiento con mis pruebas de unidad Jest, y agregar una construcción de paquete web antes de ejecutar las pruebas unitarias solo ralentizará el proceso. La respuesta del libro de texto es "moduleNameMapper"
dependencias sin código usando la opción "moduleNameMapper"
https://facebook.github.io/jest/docs/webpack.html#handling-static-assets