16. Миграция на Vite
Vite стал популярной альтернативой Webpack благодаря молниеносному dev-серверу и простой конфигурации. Однако миграция требует внимательного подхода — есть ряд нюансов и потенциальных проблем.
Почему мигрируют с Webpack на Vite?
Заголовок раздела «Почему мигрируют с Webpack на Vite?»| Критерий | Webpack | Vite |
|---|---|---|
| Старт dev-сервера | 10-60+ сек | < 1 сек |
| HMR | Секунды | Мгновенно |
| Конфигурация | Сложная | Простая |
| Build (production) | Webpack bundler | Rollup |
| Module Federation | ✅ Native | ❌ Плагин (ограниченный) |
| Legacy browsers | Webpack + Babel | @vitejs/plugin-legacy |
| Кастомные лоадеры | ✅ | Только Rollup плагины |
| Размер бандла | Схожий | Схожий |
Когда НЕ мигрировать:
- Проект использует Module Federation
- Сложные кастомные Webpack лоадеры без аналогов
- Большой enterprise проект с устоявшейся инфраструктурой
- Интеграция с SSR (Next.js, Remix — у них свои системы сборки)
Шаг 1: Установка Vite
Заголовок раздела «Шаг 1: Установка Vite»npm install --save-dev vite @vitejs/plugin-react# или для TypeScriptnpm install --save-dev vite @vitejs/plugin-react typescriptШаг 2: vite.config.ts (эквивалент webpack.config.js)
Заголовок раздела «Шаг 2: vite.config.ts (эквивалент webpack.config.js)»import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';import path from 'path';
export default defineConfig({ plugins: [react()],
// Эквивалент resolve.alias resolve: { alias: { '@': path.resolve(__dirname, 'src'), }, },
// Эквивалент devServer server: { port: 3000, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true }, }, },
// Эквивалент output build: { outDir: 'dist', sourcemap: true, rollupOptions: { output: { manualChunks: { 'react-vendor': ['react', 'react-dom'], 'router': ['react-router-dom'], }, }, }, },
// Эквивалент DefinePlugin define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), },});Шаг 3: Переменные окружения
Заголовок раздела «Шаг 3: Переменные окружения»# Webpackprocess.env.REACT_APP_API_URL
# Vite — только переменные с префиксом VITE_!import.meta.env.VITE_API_URLЕсли много переменных REACT_APP_*, используйте vite-plugin-env-compatible:
npm install --save-dev vite-plugin-env-compatibleШаг 4: index.html — из public/ в корень
Заголовок раздела «Шаг 4: index.html — из public/ в корень»<div id="root"></div><!-- Webpack вставляет <script> автоматически -->
<!-- Vite: index.html в корне проекта --><div id="root"></div><!-- Явный <script> обязателен! --><script type="module" src="/src/index.tsx"></script>Шаг 5: Эквиваленты конфигураций
Заголовок раздела «Шаг 5: Эквиваленты конфигураций»DefinePlugin → define
Заголовок раздела «DefinePlugin → define»// Webpacknew webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') })
// Vitedefine: { 'process.env.NODE_ENV': JSON.stringify('production') }HtmlWebpackPlugin → встроено в Vite
Заголовок раздела «HtmlWebpackPlugin → встроено в Vite»// Webpack: нужен плагинnew HtmlWebpackPlugin({ template: './public/index.html' })
// Vite: не нужен, index.html в корне — автоматическиCopyWebpackPlugin → vite-plugin-static-copy
Заголовок раздела «CopyWebpackPlugin → vite-plugin-static-copy»npm install --save-dev vite-plugin-static-copyimport { viteStaticCopy } from 'vite-plugin-static-copy';
plugins: [ react(), viteStaticCopy({ targets: [{ src: 'public/robots.txt', dest: '' }] }),]Шаг 6: npm scripts
Заголовок раздела «Шаг 6: npm scripts»{ "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "typecheck": "tsc --noEmit" }}Типичные проблемы при миграции
Заголовок раздела «Типичные проблемы при миграции»require() не работает
Заголовок раздела «require() не работает»// ❌ Webpack поддерживал require() в компонентахconst img = require('./logo.png');
// ✅ Vite: только ES importsimport img from './logo.png';CommonJS зависимости
Заголовок раздела «CommonJS зависимости»Некоторые npm пакеты используют только CommonJS. Vite обычно справляется автоматически через @rollup/plugin-commonjs, но иногда нужен optimizeDeps:
optimizeDeps: { include: ['some-cjs-package'],}Glob imports
Заголовок раздела «Glob imports»// ❌ Webpack require.contextconst modules = require.context('./modules', true, /\\.ts$/);
// ✅ Vite: import.meta.globconst modules = import.meta.glob('./modules/**/*.ts');Ниже — интерактивный чеклист миграции с Webpack на Vite.