Using with webpack
Jest puede ser usado en proyectos que usan webpack para manejar recursos, estilos y compilación. Webpack ofrece algunos desafíos únicos sobre otras herramientas porque se integra directamente con su aplicación para permitir la gestión de hojas de estilo, recursos como imágenes y fuentes, junto con el extenso ecosistema de lenguajes y herramientas de compilación a JavaScript.
Un ejemplo de webpack #
Vamos a comenzar con un tipo común de archivo de configuración webpack y traducirlo a una configuración de Jest.
// webpack.config.js module.exports = { module: { loaders: [ {exclude: ['node_modules'], loader: 'babel', test: /\.jsx?$/}, {loader: 'style-loader!css-loader', test: /\.css$/}, {loader: 'url-loader', test: /\.gif$/}, {loader: 'file-loader', test: /\.(ttf|eot|svg)$/}, ], }, resolve: { alias: { config$: './configs/app-config.js', react: './vendor/react-master', }, extensions: ['', 'js', 'jsx'], modules: [ 'node_modules', 'bower_components', 'shared', '/shared/vendor/modules', ], }, };
Si tienes archivos JavaScript que son transforman por Babel, puedes Habilitar el soporte para Babel instalando el plugin de babel-jest
. Transformaciones de JavaScript que no necesitan Babel pueden manejarse con la opción de configuración de transform
de Jest.
Manejo de activos estáticos #
A continuación, vamos a configurar Jest para utilizar archivos como hojas de estilo e imágenes. Generalmente, estos archivos no son particularmente útiles en las pruebas por lo que con seguridad podemos mockearlos. Sin embargo, si utiliza módulos de CSS entonces es mejor mockear un proxy para las búsquedas de className.
// package.json { "jest": { "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js", "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js" } } }
Y mockear los archivos propios:
// __mocks__/styleMock.js module.exports = {};
// __mocks__/fileMock.js module.exports = 'test-file-stub';
Mockear Modulos de CSS #
Puede utilizar un ES6 Proxy para mockear Modulos de CSS:
npm install --save-dev identity-obj-proxy
A continuación, se devolverán todas tus búsquedas de className del objeto estilos como (p. ej., styles.foobar === 'foobar'
). Esto es bastante útil para React Snapshot Testing.
// package.json (for CSS Modules) { "jest": { "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js", "\\.(css|less)$": "identity-obj-proxy" } } }
Aviso que Proxy está habilitado en Node 6 por defecto. Si aún no estas utilizando Node 6, asegúrate de que invocas Jest usando
node --harmony_proxies node_modules/.bin/jest
.
Si moduleNameMapper
no puede satisfacer tus necesidades, puedes utilizar transform
comor opción de configuración Jest para especificar cómo se transforman los activos. Por ejemplo, un transformador que devuelve el nombre de un archivo (como require('logo.jpg');
devuelve 'logo'
) puede ser escrito como:
// fileTransformer.js const path = require('path'); module.exports = { process(src, filename, config, options) { return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; }, };
// package.json (for custom transformers and CSS Modules) { "jest": { "moduleNameMapper": { "\\.(css|less)$": "identity-obj-proxy" }, "transform": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js" } } }
Si hemos dicho a Jest que omita archivos que coinciden con una extensión de hoja de estilo o imagen, y por el contrario, necesita nuestros archivos de mock. Puedes ajustar a una expresión regular para que coincida con el tipo de archivos de configuración webpack.
Nota: Si utiliza babel-jest con preprocesadores de código adicional, debe definir explícitamente babel-jest como un transformador para el código JavaScript y asignar archivos .js
en el módulo de babel-jest.
"transform": { "^.+\\.js$": "babel-jest", "^.+\\.css$": "custom-transformer", ... }
Configurar Jest para que encuentre nuestros archivos #
Ahora que Jest sabe cómo procesar nuestros archivos, tenemos que decirle cómo encontrarlos. Para modulesDirectories
de webpack y extensions
allí las opciones son análogos directos en opciones de Jest moduleDirectories
y moduleFileExtensions
.
// package.json { "jest": { "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
Nota: <rootdir> es un símbolo especial que se reemplaza por Jest con la raíz de tu proyecto. La mayoría de las veces se trata de la carpeta donde tu package.json se encuentra a menos que especifiques una opción personalizada
rootDir
en tu configuración.
Asimismo la opción de webpack resolve.root
como la variable env NODE_PATH
, que establece o hacen uso de la opción modulePaths
.
// package.json { "jest": { "modulePaths": [ "/shared/vendor/modules" ], "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
Y por último sólo tenemos webpack alias
izquierda para manejar. Para ello podemos hacer uso de la opción de moduleNameMapper
otra vez.
// package.json { "jest": { "modulePaths": [ "/shared/vendor/modules" ], "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "^react(.*)$": "<rootDir>/vendor/react-master$1", "^config$": "<rootDir>/configs/app-config.js", "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
¡Eso es todo! webPack es una herramienta compleja y flexible, por lo que tendrás que hacer algunos ajustes para manejar las necesidades específicas de tu aplicación. Afortunadamente para la mayoría de los proyectos, Jest debe ser lo suficientemente flexible como para manejar tu configuración webpack.
Nota: Para las más complejas configuraciones webpack, también puedes investigar proyectos tales como: babel-plugin-webpack-loaders.
Utilizando webpack 2 #
webPack 2 ofrece soporte nativo para los módulos de ES. Sin embargo, Jest funciona en Node y por lo tanto requiere que los módulos ES sean transpilados a los módulos de CommonJS. Como tal, si usas webpack 2, probablemente querrás configurar que Babel transpile módulos de ES a módulos de CommonJS sólo en el entorno de pruebas
.
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "env": { "test": { "plugins": ["transform-es2015-modules-commonjs"] } } }
Nota: Jest cachea archivos para acelerar la ejecución de los tests. Si ha actualizado .babelrc y Jest sigue sin funcionar, intente ejecutar Jest con
--no-cache
.
Si utilizas las importaciones dinámicas (import('some-file.js').then (módulo = >...)
), es necesario activar el plugin de dynamic-import-node
.
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "plugins": ["syntax-dynamic-import"], "env": { "test": { "plugins": ["dynamic-import-node"] } } }