Использование с webpack
Jest можно использовать в проектах, которые используют webpack для управления активами, стилями и компиляцией. webpack предлагает некоторые уникальные проблемы по сравнению с другими инструментами, так как он интегрируется непосредственно с вашим приложением для управления стилями, активами, такими как изображения и шрифты, а также с обширной экосистемой языков и инструментов, компилируемых в JavaScript.
Пример с webpack
Давайте начнем с типичного файла конфигурации webpack и переведем его в настройку Jest.
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',
],
},
};
Если у вас есть файлы JavaScript, которые преобразуются с помощью Babel, вы можете включить поддержку Babel, установив плагин babel-jest. Преобразования JavaScript, не связанные с Babel, можно обработать с помощью параметра конфигурации Jest transform.
Обработка статических активов
Далее, давайте настроим Jest для корректной обработки файлов активов, таких как стили и изображения. Обычно эти файлы не очень полезны в тестах, поэтому мы можем безопасно их смокировать. Однако, если вы используете CSS Modules, лучше смокировать прокси для поиска ваших className.
{
"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"
}
}
}
И сами файлы-заглушки:
module.exports = {};
module.exports = 'test-file-stub';
Имитация CSS Modules
Можно использовать ES6 Proxy для имитации CSS Modules:
- npm
- Yarn
npm install --save-dev identity-obj-proxy
yarn add --dev identity-obj-proxy
Тогда все ваши запросы className в объекте styles будут возвращаться как есть (например, styles.foobar === 'foobar'). Это очень удобно для тестирования снимков React.
{
"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"
}
}
}
Если 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))};`,
};
},
};
{
"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"
}
}
}
Мы сказали Jest игнорировать файлы, соответствующие расширениям стилей или изображений, и вместо этого использовать наши файлы-заглушки. Вы можете изменить регулярное выражение для соответствия типам файлов, обрабатываемым вашей конфигурацией webpack.
Не забудьте явно включить дефолтный babel-jest преобразователь, если вы хотите использовать его вместе с дополнительными препроцессорами кода:
"transform": {
"\\.[jt]sx?$": "babel-jest",
"\\.css$": "some-css-transformer",
}
Настройка Jest для поиска наших файлов
Теперь, когда Jest знает, как обрабатывать наши файлы, нам нужно сказать ему, как их найти. Для опций webpack modulesDirectories и extensions существуют прямые аналоги в опциях Jest moduleDirectories и moduleFileExtensions.
{
"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"
}
}
}
Примечание:
<rootDir>— это специальный маркер, который Jest заменяет корнем вашего проекта. Большинство раз это будет папка, где находится вашpackage.json, если вы не укажете пользовательскийrootDirпараметр в вашей конфигурации.
Аналогично, опция webpack resolve.root выполняет функцию установки переменной среды NODE_PATH, которую вы можете установить или использовать modulePaths параметр.
{
"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"
}
}
}
И, наконец, нам нужно обработать webpack alias. Для этого мы можем снова использовать параметр moduleNameMapper.
{
"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",
"^react(.*)$": "<rootDir>/vendor/react-master$1",
"^config$": "<rootDir>/configs/app-config.js"
}
}
}
Вот и все! webpack — сложный и гибкий инструмент, поэтому вам может потребоваться внести некоторые коррективы для обработки специфических потребностей вашего приложения. К счастью, для большинства проектов Jest должен быть достаточно гибким, чтобы справиться с вашей конфигурацией webpack.
Примечание: Для более сложных конфигураций webpack вы также можете изучить проекты, такие как: babel-plugin-webpack-loaders.
Использование с webpack 2
webpack 2 предлагает встроенную поддержку ES модулей. Однако Jest работает в Node и, следовательно, требует транспиляции ES модулей в CommonJS модули. Таким образом, если вы используете webpack 2, вам, скорее всего, понадобится настроить Babel для транспиляции ES модулей в CommonJS модули только в среде test.
{
"presets": [["env", {"modules": false}]],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Примечание: Jest кеширует файлы для ускорения выполнения тестов. Если вы обновили .babelrc, а Jest всё ещё не работает, попробуйте запустить Jest с
--no-cache.
Если вы используете динамические импорты (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, Redux и Node можно посмотреть здесь.
© 2022 Facebook, Inc.
Licensed under the MIT License.
https://jestjs.io/docs/webpack