Использование с 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 Modules, лучше подменить их прокси-объектом для поиска 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 Modules
Для имитации CSS Modules можно использовать прокси ES6:
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev identity-obj-proxy
yarn add --dev identity-obj-proxy
pnpm add --save-dev identity-obj-proxy
bun add --dev identity-obj-proxy
Тогда при каждом поиске className в объекте styles будет возвращаться исходное значение (например, 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
Теперь, когда Jest умеет обрабатывать наши файлы, нужно указать ему, как их находить. Параметрам 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.
Аналогом resolve.roots в webpack (альтернативой настройке NODE_PATH) в Jest является 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',
},
};
Наконец, нужно обработать параметр webpack alias. Для этого можно снова воспользоваться параметром moduleNameMapper.
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
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/preset-env
yarn add --dev @babel/preset-env
pnpm add --save-dev @babel/preset-env
bun add --dev @babel/preset-env
Затем настройте Babel следующим образом:
{
"presets": ["@babel/preset-env"]
}
Jest кэширует файлы, чтобы ускорить выполнение тестов. Если вы обновили .babelrc и Jest работает не так, как ожидалось, попробуйте очистить кэш, выполнив jest --clearCache.
Если вы используете динамические импорты (import('some-file.js').then(module => ...)), необходимо включить плагин dynamic-import-node.
{
"presets": [["env", {"modules": false}]],
"plugins": ["syntax-dynamic-import"],
"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
}
Пример использования Jest с webpack и React можно посмотреть здесь.
© 2022 Facebook, Inc.
Licensed under the MIT License.
https://jestjs.io/docs/webpack