Spec-Zone.ru › Jest

Использование с 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',
    ],
  },
};
webpack.config.js

Если файлы 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',
  },
};
jest.config.js

А вот сами файлы-заглушки:

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

Имитация 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',
  },
};
jest.config.js (для CSS Modules)

Если 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))};`,
    };
  },
};
fileTransformer.js
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.config.js (для пользовательских преобразователей и CSS Modules)

Мы указали 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',
  },
};
jest.config.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',
  },
};
jest.config.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',
  },
};
jest.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"]
}
.babelrc
совет

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"]
    }
  }
}
.babelrc

Пример использования Jest с webpack и React можно посмотреть здесь.

© 2022 Facebook, Inc.
Licensed under the MIT License.
https://jestjs.io/docs/webpack

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API