Перейти до основного змісту
Версія: Next

Використання з webpack

Jest може застосовуватися в проектах, які використовують webpack для керування ресурсами, стилями та компіляції коду. Порівнюючи з іншими, webpack ставить перед користувачами деякі особливі задачі, бо він напряму інтегрується у ваш застосунок для керування таблицями стилів, статичними файлами (зображень, шрифтів), разом з дедалі більшою екосистемою мов, що компілюють JavaScript, та інструментів.

Приклад використання з Webpack

Давайте почнемо із поширеного типу конфігурації webpack і створимо на його основі конфігурацію 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',
],
},
};

Якщо у вас є JavaScript файли, трансформовані за допомогою Babel, ви можете увімкнути підтримку Babel, встановивши плагін babel-jest. JavaScript перетворення, до яких не залучено Babel, Jest може проводити за допомогою опції конфігурації transform.

Обробка статичних ресурсів

Тепер давайте налаштуємо Jest для коректної обробки статичних файлів, таких, к стилі та зображення. Зазвичай ці файли непотрібні для тестів, а отже ми можемо просто їх імітувати. Проте, якщо ви використовуєте CSS модулі, краще імітувати проксі об’єкт для пошуку ваших 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',
},
};

І вміст мок модулів:

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

Імітація CSS модулів

Ви можете використати ES6 Proxy для імітації CSS модулів:

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

Тоді запит className з об’єкта стилів буде повернутий як є (наприклад, styles.foobar === 'foobar'). Це дуже зручно для тестування зі знімками React компонентів.

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',
},
};

Якщо moduleNameMapper не відповідає вашим вимогам, можна використовувати опцію конфігурації Jest transform для вказання способу трансформації статичних файлів. Наприклад, перетворювач, що повертає базове ім'я файлу (як require('logo.jpg'); повертає 'logo') може мати наступний вигляд:

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',
},
};

Ми вказали Jest ігнорувати файли, які відповідають розширенню стилів та зображень, і, замість цього, викликати наші мок файли. Ви можете налаштувати решулярні вирази, щоб обробляти типи файлів, які обробляє ваша конфігурація webpack.

порада

Не забудьте явно додати babel-jest, якщо ви хочете використовувати його разом з додатковими препроцесорами коду:

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

Налаштування Jest для пошуку файлів

Now that Jest knows how to process our files, we need to tell it how to find them. Для webpack параметрів modules та extensions в Jest маються аналоги у вигляді moduleDirectories та moduleFileExtensions.

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',
},
};
note

<rootDir> - це спеціальний токен, який Jest замінює на кореневий каталог вашого проєкту. В більшості випадків, це буде каталог, який містить ваш package.json, за винятком, коли ви вказали власний параметр rootDir у вашій конфігурації.

Аналогічно, Jest варіацією Webpack параметру resolve.roots (альтернатива заданню NODE_PATH) є 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',
},
};

Ось і все! webpack - це складний і гнучкий інструмент, тому вам, можливо, доведеться зробити деякі додаткові налаштування, щоб підтримувати специфічні вимоги вашого проекту. На щастя, для більшості проектів, Jest повинен бути більш ніж достатньо гнучкими, щоб підтримувати ваші конфігурації webpack.

порада

Для складніших webpack конфігурацій, корисним може бути ознайомлення з такими проєктами, як babel-plugin-webpack-loaders.

Використання з webpack

На додачу до встановлення babel-jest, як описувалось раніше, вам треба буде додати @babel/preset-env:

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

Після цього, ви можете налаштувати Babel наступним чином:

.babelrc
{
"presets": ["@babel/preset-env"]
}
порада

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.

порада

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.