Використання з webpack
Jest може застосовуватися в проектах, які використовують webpack для керування ресурсами, стилями та компіляції коду. Порівнюючи з іншими, webpack ставить перед користувачами деякі особливі задачі, бо він напряму інтегрується у ваш застосунок для керування таблицями стилів, статичними файлами (зображень, шрифтів), разом з дедалі більшою екосистемою мов, що компілюють JavaScript, та інструментів.
Приклад використання з Webpack
Давайте почнемо із поширеного типу конфігурації webpack і створимо на його основі конфігурацію Jest.
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.
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',
},
};
І вміст мок модулів:
module.exports = {};
module.exports = 'test-file-stub';
Імітація CSS модулів
Ви можете використати ES6 Proxy для імітації CSS модулів:
- npm
- Yarn
- pnpm
npm install --save-dev identity-obj-proxy
yarn add --dev identity-obj-proxy
pnpm add --save-dev identity-obj-proxy
Тоді запит className з об’єкта стилів буде повернутий як є (наприклад, styles.foobar === 'foobar'
). Це дуже зручно для тестування зі знімками React компонентів.
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'
) може мати наступний вигляд:
const path = require('path');
module.exports = {
process(sourceText, sourcePath, options) {
return {
code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
};
},
};
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
.
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',
},
};
<rootDir>
- це спеціальний токен, який Jest замінює на кореневий каталог вашого проєкту. В більшості випадків, це буде каталог, який містить ваш package.json
, за винятком, коли ви вказали власний параметр rootDir
у вашій конфігурації.
Аналогічно, Jest варіацією Webpack параметру resolve.roots
(альтернатива заданню NODE_PATH
) є modulePaths
.
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',
},
};