Типичные проблемы при миграции

Миграция с Webpack, Vue CLI, Create React App или Parcel на Vite почти всегда сопровождается набором повторяющихся проблем, связанных не столько с самим Vite, сколько с различиями в архитектуре сборки, модели модулей и способе обработки ассетов. Большая часть ошибок проявляется не сразу, а на этапе сборки production или при переходе от привычной конфигурации к ESM-ориентированной модели. ### Переход на ESM и отказ от CommonJS Одной из ключевых причин сбоев становится переход Vite на нативные ES-модули в разработке. Старые проекты часто активно используют `require`, `module.exports` и смешанные импорты. Типичные проявления проблемы: * ошибки вида `require is not defined` * невозможность загрузки некоторых библиотек в dev-режиме * несовместимость с CJS-only пакетами Vite частично решает это через pre-bundling зависимостей с помощью esbuild, однако остаются случаи, когда: * библиотека не имеет ESM-сборки * экспорт реализован нестандартно * используется динамический `require` Решения обычно сводятся к: * явному указанию оптимизации зависимостей через `optimizeDeps` * замене импортов на ESM-совместимые версии библиотек * использовании `createRequire` в редких Node-специфичных случаях ### Различия в работе с переменными окружения В старых сборщиках широко используется `process.env`. В Vite модель принципиально иная: доступ к окружению осуществляется через `import.meta.env`. Проблемы миграции: * `process is not defined` в браузере * переменные не подхватываются в рантайме * различия между dev и build окружением Особенности Vite: * переменные должны начинаться с префикса `VITE_` * доступ только через `import.meta.env.VITE_*` * разные режимы (`development`, `production`, кастомные mode) Часто требуется массовая замена: * `process.env.API_URL` → `import.meta.env.VITE_API_URL` ### Обработка статических ассетов В Webpack и Vue CLI существует привычная модель загрузчиков (`file-loader`, `url-loader`). Vite использует иную стратегию: ассеты обрабатываются как ESM-импорты. Типичные проблемы: * некорректные пути к изображениям * поломка динамических URL * различия между `public` и `src/assets` Особенности: * всё внутри `src` обрабатывается через import graph * папка `public` копируется без трансформации * доступ к ассетам через `new URL('./img.png', import.meta.url)` Частая ошибка — использование строковых путей: * `img: "/assets/logo.png"` может работать в dev, но ломаться в build при изменении `base` ### Проблемы с base path и деплоем Vite строго разделяет базовый путь приложения через параметр `base`. Типовые ошибки: * приложение работает локально, но ломается на проде * неверные пути к JS и CSS чанкам * 404 на статические файлы Причины: * отсутствие настройки `base` при деплое в подкаталог * ожидание поведения Webpack publicPath Решение обычно связано с явным указанием: * `base: '/app/'` для подкаталога * или `base: './'` для относительной раздачи ### Различия dev-сервера и production-сборки Vite использует dev-сервер на основе native ESM, а production — через Rollup. Проблемы: * поведение кода отличается между dev и build * динамические импорты работают в dev, но ломаются в build * плагины ведут себя по-разному Особенно часто встречается: * ошибки code splitting * отсутствие чанков в production * некорректная загрузка lazy routes Причина в том, что: * dev использует on-demand трансформацию * build строит статический граф модулей ### Конфликты с алиасами и резолвингом путей В старых проектах часто используется `@` или кастомные алиасы через Webpack. Типичные проблемы: * алиасы не распознаются * TypeScript понимает пути, а Vite нет * различия между dev и IDE В Vite требуется явная настройка: * `resolve.alias` в `vite.config.js` Также часто возникает рассинхронизация: * `tsconfig.json` paths * Vite alias * Jest alias (если используется) ### Проблемы с CSS и препроцессорами Vite поддерживает CSS нативно, но поведение отличается от Webpack pipeline. Частые проблемы: * Sass переменные не подхватываются глобально * порядок подключения стилей меняется * CSS Modules ведут себя иначе Особенности: * каждый `.vue` или `.module.css` обрабатывается изолированно * глобальные стили нужно подключать явно * PostCSS конфигурация должна быть вынесена корректно ### Ошибки при работе с динамическими импортами Vite строго анализирует `import()` выражения. Проблемы: * динамические пути вида `import(path)` не работают * требуется статическая часть пути * Webpack-подобные конструкции ломаются Пример проблемного кода: * `import(\`./views/${name}.vue`)` В Vite требуется: * `import.meta.glob` * или явное перечисление модулей ### import.meta.glob и различие с Webpack context Webpack использует `require.context`, тогда как Vite предлагает `import.meta.glob`. Типичные проблемы: * отсутствие привычного API * неправильное использование glob-паттернов * неожиданный формат возвращаемых модулей Особенность Vite: * результат — объект функций импорта * требуется дополнительная обработка `.then(m => m.default)` ### Проблемы с Node.js polyfills Vite не предоставляет автоматические polyfills для Node встроенных модулей. Ошибки: * `Buffer is not defined` * `process is not defined` * `path`, `crypto`, `stream` отсутствуют Причина: * Vite ориентирован на браузер * Webpack раньше часто включал polyfills по умолчанию Решения: * явное подключение polyfill-библиотек * настройка `resolve.alias` для Node модулей * отказ от Node-зависимых библиотек в фронтенде ### Конфликты с зависимостями и optimizeDeps Vite заранее предсобирает зависимости через esbuild. Проблемы: * зависимость не обновляется после изменения * stale cache приводит к странным багам * некоторые пакеты игнорируются prebundle Симптомы: * изменения в node_modules не отражаются * ошибка оптимизации зависимостей Решения: * очистка `node_modules/.vite` * настройка `optimizeDeps.include/exclude` ### Проблемы с legacy-браузерами Vite по умолчанию ориентирован на современные браузеры. Ошибки: * отсутствие поддержки IE11 * некорректная работа старых Safari * отсутствие транспиляции без плагина legacy Причина: * минимизация transpilation overhead * использование native ESM Для старых окружений требуется: * `@vitejs/plugin-legacy` ### Несовместимость плагинов Webpack Одна из самых частых проблем — попытка перенести Webpack loader напрямую. Ошибки: * `style-loader`, `file-loader` не работают * Babel loader конфигурации теряют смысл * плагины SSR требуют переписывания В Vite используется: * plugin-based архитектура Rollup * специфические Vite-плагины вместо loader-цепочек ### Проблемы с HMR Hot Module Replacement в Vite работает иначе, чем в Webpack. Типичные проблемы: * состояние компонента сбрасывается * обновления приходят не туда * HMR не срабатывает при глубокой вложенности Причина: * иной механизм инвалидации модулей * более агрессивный dependency graph ### Monorepo и workspace сложности В монорепозиториях часто возникают проблемы с резолвингом зависимостей. Симптомы: * дублирование пакетов * ошибки при импорте локальных библиотек * некорректный pre-bundling Причины: * Vite не всегда корректно резолвит hoisted dependencies * необходимость ручной настройки `server.fs.allow` ### Различия в сборке чанков Rollup внутри Vite генерирует другую структуру чанков, чем Webpack. Проблемы: * изменённые имена файлов * нестабильный hash * неожиданный split vendor-кода Это влияет на: * кеширование * CDN стратегии * интеграцию с backend шаблонами ### Проблемы с proxy и dev API Dev-сервер Vite требует явной настройки proxy. Ошибки: * CORS в development * запросы идут не на backend * различия между dev и prod endpoints Причина: * Vite не навязывает backend интеграцию * proxy конфиг заменяет Webpack devServer proxy ### Итоговая картина миграционных проблем Основные сложности при переходе на Vite формируются вокруг трёх направлений: переход на ESM-модель, изменение pipeline обработки ассетов и различие между dev и production архитектурами. Большинство ошибок не связано с самим Vite, а является следствием удаления скрытых абстракций, которые раньше предоставлял Webpack и его экосистема loaders/plugins.