Конфигурация модульных сборщиков (Webpack, Vite)

Vue Test Utils работает поверх среды выполнения JavaScript и напрямую зависит от конфигурации сборщика. Именно сборщик отвечает за:

  • обработку *.vue файлов;
  • поддержку алиасов (@, ~);
  • трансформацию ES-модулей;
  • работу с CSS, изображениями и другими ассетами;
  • согласованность окружения тестов с production-сборкой.

Неправильная или неполная конфигурация приводит к ошибкам импорта, падениям тестов и расхождениям поведения компонентов.


Базовые требования Vue Test Utils к сборщику

Для корректной работы тестов требуется:

  • поддержка Single File Components (.vue);
  • компиляция шаблонов Vue;
  • единый resolver модулей для приложения и тестов;
  • возможность подмены зависимостей (mocks, stubs);
  • корректная обработка process.env.

Тестовый раннер (Jest, Vitest) не заменяет сборщик — он лишь использует его конфигурацию или её адаптацию.


Конфигурация Webpack для тестирования Vue

Обработка .vue файлов

Webpack требует явного подключения vue-loader и соответствующего плагина:

// webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ]
}

Без этого Vue Test Utils не сможет смонтировать компонент — шаблон не будет скомпилирован.


Алиасы модулей

Алиасы должны полностью совпадать с используемыми в коде приложения:

resolve: {
  alias: {
    '@': path.resolve(__dirname, 'src')
  },
  extensions: ['.js', '.vue', '.json']
}

Это критично для корректной работы mount() и shallowMount() при импорте компонентов и composable-функций.


Поддержка ES-модулей и Babel

Jest и Webpack используют разные механизмы трансформации. Для единообразия необходим babel-loader:

{
  test: /\.js$/,
  exclude: /node_modules/,
  use: {
    loader: 'babel-loader'
  }
}

Без этого возможны ошибки при использовании optional chaining, nullish coalescing и других современных конструкций.


Игнорирование стилей и ассетов

В тестах стили и изображения не имеют значения и должны быть заглушены:

{
  test: /\.(css|scss)$/,
  use: ['null-loader']
}

Или через Jest:

moduleNameMapper: {
  '\\.(css|scss)$': 'identity-obj-proxy'
}

Интеграция Webpack с Jest

Webpack-конфигурация не используется Jest напрямую, но ключевые элементы должны быть продублированы.

moduleNameMapper

moduleNameMapper: {
  '^@/(.*)$': '<rootDir>/src/$1'
}

transform

transform: {
  '^.+\\.vue$': '@vue/vue3-jest',
  '^.+\\.js$': 'babel-jest'
}

Это обеспечивает согласованность трансформации компонентов между сборкой и тестами.


Конфигурация Vite для тестирования Vue

Vite изначально ориентирован на ES-модули и значительно упрощает настройку.

Базовая конфигурация Vite

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': '/src'
    }
  }
})

Vue Test Utils автоматически использует эту конфигурацию при работе с Vitest.


Vitest как тестовый раннер для Vite

Vitest нативно интегрирован с Vite и не требует дублирования конфигурации.

Включение test-блока

export default defineConfig({
  plugins: [vue()],
  test: {
    environment: 'jsdom',
    globals: true
  }
})

jsdom необходим для корректной работы mount() и DOM-API.


Поддержка алиасов и плагинов

Vitest использует resolve.alias и plugins напрямую, поэтому:

  • алиасы работают без дополнительной настройки;
  • defineProps, script setup, JSX поддерживаются автоматически;
  • нет необходимости в moduleNameMapper.

Обработка CSS и ассетов в Vite

По умолчанию Vite игнорирует стили в тестах. Для более строгого контроля возможно явное отключение:

test: {
  css: false
}

Это ускоряет тесты и исключает влияние CSS на snapshots.


Моки глобальных зависимостей

Webpack + Jest

jest.mock('@/api/http', () => ({
  get: jest.fn()
}))

При этом путь должен быть разрешаемым через moduleNameMapper.


Vite + Vitest

vi.mock('@/api/http', () => ({
  get: vi.fn()
}))

Механизм работает поверх ES-модулей и использует resolver Vite без дополнительной настройки.


Работа с process.env и import.meta.env

Webpack

new webpack.DefinePlugin({
  'process.env': JSON.stringify(process.env)
})

Без этого возможны ошибки при доступе к process.env.NODE_ENV в компонентах.


Vite

Используется import.meta.env:

if (import.meta.env.DEV) {
  // логика разработки
}

Vitest автоматически подставляет значения окружения из Vite-конфигурации.


Snapshot-тесты и сборщик

Различия в конфигурации сборщика напрямую влияют на snapshot-тесты:

  • порядок атрибутов;
  • auto-import компонентов;
  • глобальные директивы;
  • поведение scoped-стилей.

Для стабильности snapshots необходимо:

  • единый набор плагинов;
  • одинаковая версия Vue;
  • отключение CSS при необходимости;
  • минимизация глобальной логики в app.config.

Типичные ошибки конфигурации

  • Несовпадение алиасов между сборкой и тестами
  • Отсутствие vue-loader или @vitejs/plugin-vue
  • Использование Jest без jsdom
  • Попытка тестировать Vite-проект через Webpack
  • Дублирование конфигураций вместо повторного использования

Рекомендации по архитектуре конфигурации

  • Использовать один источник правды для алиасов
  • Минимизировать логику сборщика в тестах
  • Для новых проектов предпочитать Vite + Vitest
  • Для legacy-проектов изолировать Webpack-конфигурацию тестов
  • Не смешивать CommonJS и ES-модули в одном пайплайне

Такой подход обеспечивает предсказуемую, воспроизводимую и масштабируемую среду модульного тестирования Vue-компонентов.