Using with webpack
Jest може застосовуватися в проектах, які використовують webpack для керування ресурсами, стилями та компіляції коду. Webpack кидає певні унікальні виклики щодо використання інших інструментів, оскільки він інтегрується безпосередньо в ваш додаток, дозволяючи керувати файлами стилів, зображень, шрифтів, разом з розвиненою екосистемою компіляції в JavaScript інших мов та інструментів.
Приклад використання з Webpack #
Давайте почнемо із поширеного типу конфігурації webpack і створимо на його основі конфігурацію Jest.
// webpack.config.js 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
. Трансформації, які не можуть бути виконані з використанням Babel, можна налаштувати в опції конфігурації transform
.
Обробка статичних ресурсів #
Тепер давайте налаштуємо Jest для коректної обробки статичних файлів, таких, к стилі та зображення. Зазвичай ці файли непотрібні для тестів, а отже ми можемо просто їх імітувати. Проте, якщо ви використовуєте CSS модулі, краще імітувати проксі об’єкт для пошуку ваших className.
// package.json { "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" } } }
І вміст мок модулів:
// __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 компонентів.
// package.json (для CSS Modules) { "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" } } }
Зверніть увагу, що Proxy увімкнуті в Node 6 за замовчуванням. Якщо ви ще не використовуєте Node 6 або вище, переконайтеся, що ви викликаєте Jest командою
node --harmony_proxies node_modules/.bin/jest
.
Якщо moduleNameMapper
не задовольняє ваші вимоги, ви можете скористатися параметром конфігурації transform
, щоб вказати як саме ресурси повинні бути перетворені. Наприклад, обробник, який повертає ім’я файлу (так, щоб виклик require('logo.jpg');
повертав 'logo'
), може виглядати так:
// fileTransformer.js const path = require('path'); module.exports = { process(src, filename, config, options) { return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; }, };
// package.json (for custom transformers and CSS Modules) { "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 з додатковими препроцесорами коду, вам потрібно явно вказати babel-jest, як обробник вашого JavaScript коду, вказавши для трансформації файлів з розширеннями .js
модуль babel-jest.
"transform": { "^.+\\.js$": "babel-jest", "^.+\\.css$": "custom-transformer", ... }
Налаштування Jest для пошуку файлів #
Тепер, коли Jest знає як обробляти наші файли, нам потрібно пояснити йому, як їх знайти. Для параметрів webpack modulesDirectories
та extensions
є прямі аналоги в Jest: moduleDirectories
та moduleFileExtensions
.
// package.json { "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
в конфігурації Jest.
Встановлення змінної оточення NODE_PATH
працює так само, як і параметр webpack resolve.root
. Також ви можете використати параметр Jest modulePaths
.
// package.json { "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
. Для цього ми можемо знову використати параметр Jest moduleNameMapper
.
// package.json { "jest": { "modulePaths": [ "/shared/vendor/modules" ], "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "^react(.*)$": "<rootDir>/vendor/react-master$1", "^config$": "<rootDir>/configs/app-config.js", "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
Ось і все! webpack - це складний і гнучкий інструмент, тому вам, можливо, доведеться зробити деякі додаткові налаштування, щоб підтримувати специфічні вимоги вашого проекту. На щастя, для більшості проектів, Jest повинен бути більш ніж достатньо гнучкими, щоб підтримувати ваші конфігурації webpack.
Примітка: Для підтримки більш складних конфігурацій webpack ви також можете ознайомитися з такими проектами, як: babel-plugin-webpack-loaders.
Використання з webpack 2 #
webpack 2 пропонує вбудовану підтримку для ES модулів. Однак, Jest працює в Node і тому вимагає, щоб ES модулі були перетворені в CommonJS модулі. Таким чином, якщо ви використовуєте webpack 2, вам, скоріше за все, потрібно буде налаштувати Babel для перетворення ES модулів в CommonJS тільки для середовища test
.
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "env": { "test": { "plugins": ["transform-es2015-modules-commonjs"] } } }
Примітка: Jest кешує файли, щоб пришвидшити виконання тестів. Якщо ви оновили .babelrc, але Jest досі не працює, спробуйте запустити Jest з параметром
--no-cache
.
Якщо ви використовуєте динамічний імпорт (import('some-file.js').then (module = >...)
), вам необхідно включити dynamic-import-node
плагін.
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "plugins": ["syntax-dynamic-import"], "env": { "test": { "plugins": ["dynamic-import-node"] } } }