Aller au contenu principal
Version : 29.7

Utilisation avec webpack

Jest can be used in projects that use webpack to manage assets, styles, and compilation. webpack does offer some unique challenges over other tools because it integrates directly with your application to allow managing stylesheets, assets like images and fonts, along with the expansive ecosystem of compile-to-JavaScript languages and tools.

Un exemple avec Webpack

Commençons par un fichier de configuration commun de webpack et transposons-le dans une configuration Jest.

webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.jsx?$/,
exclude: ['node_modules'],
use: ['babel-loader'],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.gif$/,
type: 'asset/inline',
},
{
test: /\.(ttf|eot|svg)$/,
type: 'asset/resource',
},
],
},
resolve: {
alias: {
config$: './configs/app-config.js',
react: './vendor/react-master',
},
extensions: ['.js', '.jsx'],
modules: [
'node_modules',
'bower_components',
'shared',
'/shared/vendor/modules',
],
},
};

If you have JavaScript files that are transformed by Babel, you can enable support for Babel by installing the babel-jest plugin. Non-Babel JavaScript transformations can be handled with Jest's transform config option.

Gestion des ressources statiques

Ensuite, configurons Jest pour qu'il gère de manière efficace les fichiers de ressources tels que les feuilles de style et les images. En général, ces fichiers ne sont pas particulièrement utiles dans les tests, nous pouvons donc les éliminer sans risque. Toutefois, si vous utilisez des modules CSS, il est préférable de simuler un proxy pour vos recherches de className.

jest.config.js
module.exports = {
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',
},
};

Et les fichiers simulés eux-mêmes :

__mocks__/styleMock.js
module.exports = {};
__mocks__/fileMock.js
module.exports = 'test-file-stub';

Simulé CSS Modules

You can use an ES6 Proxy to mock CSS Modules:

npm install --save-dev identity-obj-proxy

Then all your className lookups on the styles object will be returned as-is (e.g., styles.foobar === 'foobar'). This is pretty handy for React Snapshot Testing.

jest.config.js (for CSS Modules)
module.exports = {
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',
},
};

If moduleNameMapper cannot fulfill your requirements, you can use Jest's transform config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that require('logo.jpg'); returns 'logo') can be written as:

fileTransformer.js
const path = require('path');

module.exports = {
process(sourceText, sourcePath, options) {
return {
code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
};
},
};
jest.config.js (for custom transformers and CSS Modules)
module.exports = {
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',
},
};

Nous avons dit à Jest d'ignorer les fichiers correspondant à une extension de feuille de style ou d'image, et à la place, de demander nos fichiers simulés. Vous pouvez ajuster l'expression régulière pour qu'elle corresponde aux types de fichiers que votre configuration webpack gère.

astuce

Remember to include the default babel-jest transformer explicitly, if you wish to use it alongside with additional code preprocessors:

"transform": {
"\\.[jt]sx?$": "babel-jest",
"\\.css$": "some-css-transformer",
}

Configuration de Jest pour trouver nos fichiers

Now that Jest knows how to process our files, we need to tell it how to find them. For webpack's modules, and extensions options there are direct analogs in Jest's moduleDirectories and moduleFileExtensions options.

jest.config.js
module.exports = {
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: ['node_modules', 'bower_components', 'shared'],

moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.js',
},
};
remarque

<rootDir> is a special token that gets replaced by Jest with the root of your project. Most of the time this will be the folder where your package.json is located unless you specify a custom rootDir option in your configuration.

Similarly, Jest's counterpart for Webpack's resolve.roots (an alternative to setting NODE_PATH) is modulePaths.

jest.config.js
module.exports = {
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',
},
};

And finally, we have to handle the webpack alias. For that, we can make use of the moduleNameMapper option again.

jest.config.js
module.exports = {
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',

'^react(.*)$': '<rootDir>/vendor/react-master$1',
'^config$': '<rootDir>/configs/app-config.js',
},
};

C'est tout ! webpack est un outil complexe et flexible. Il se peut donc que vous deviez procéder à quelques ajustements pour répondre aux besoins spécifiques de votre application. Heureusement pour la plupart des projets, Jest devrait être plus que suffisamment flexible pour gérer votre configuration webpack.

astuce

For more complex webpack configurations, you may also want to investigate projects such as: babel-plugin-webpack-loaders.

Utilisation avec webpack

In addition to installing babel-jest as described earlier, you'll need to add @babel/preset-env like so:

npm install --save-dev @babel/preset-env

Then, you'll want to configure Babel as follows:

.babelrc
{
"presets": ["@babel/preset-env"]
}
astuce

Jest caches files to speed up test execution. If you updated .babelrc and Jest is not working as expected, try clearing the cache by running jest --clearCache.

astuce

If you use dynamic imports (import('some-file.js').then(module => ...)), you need to enable the dynamic-import-node plugin.

.babelrc
{
"presets": [["env", {"modules": false}]],

"plugins": ["syntax-dynamic-import"],

"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
}

For an example of how to use Jest with webpack with React, you can view one here.