## Архитектурные различия Parcel и Vite как основа миграции
Parcel и Vite решают задачу сборки фронтенд-приложений, но используют принципиально разные подходы. Parcel стремится к «zero-config» модели с автоматическим анализом зависимостей и агрессивной транспиляцией всего графа проекта. Vite, напротив, разделяет режим разработки и режим сборки, опираясь на нативные ES Modules в dev-режиме и Rollup в production.
Ключевое различие, влияющее на миграцию:
* Parcel строит и обрабатывает весь граф зависимостей сразу
* Vite в dev-режиме обрабатывает модули по запросу браузера
* Parcel активно использует трансформации на лету через собственный пайплайн
* Vite использует esbuild для предварительной оптимизации и Rollup-подобную модель бандлинга
Эти различия напрямую влияют на структуру проекта, плагины, обработку ассетов и конфигурацию окружений.
## Анализ структуры проекта Parcel перед переносом
Перед переходом на Vite важно разобрать существующую структуру проекта Parcel. Типичный проект включает:
* entry-файл (index.html или index.js)
* импорт CSS напрямую в JavaScript
* встроенную обработку изображений и шрифтов
* использование `.env` через parcel-resolver
* отсутствие явного конфигурационного файла или минимальный `.parcelrc`
Parcel часто скрывает важные детали сборки, поэтому миграция начинается с выявления неявных зависимостей.
Особое внимание уделяется:
* динамическим импортам
* alias-резолвингу
* специфическим трансформациям (Babel, PostCSS, TypeScript)
* кастомным плагинам Parcel
## Базовая замена входной точки
Parcel допускает HTML как entry point, где зависимости подтягиваются автоматически:
```html
```
Vite также поддерживает HTML как точку входа, но требует явной структуры проекта.
Минимальная структура Vite:
```
index.html
src/
main.js
```
В `index.html`:
```html
```
Основное отличие заключается в обязательном указании `type="module"`, так как Vite работает через native ESM.
## Перенос зависимостей и npm-пакетов
Parcel автоматически полифиллит и резолвит многие зависимости. Vite требует более явного подхода.
Типичные изменения:
### 1. Установка зависимостей
Все зависимости должны быть установлены явно:
```bash
npm install react react-dom
```
### 2. Удаление Parcel-специфичных пакетов
Удаляются:
* `parcel`
* `@parcel/transformer-*`
* `@parcel/config-default`
* `parcel-bundler` (legacy)
### 3. Проверка side effects
Vite строго учитывает `package.json` поле:
```json
{
"sideEffects": false
}
```
Если проект использует CSS или polyfills через side effects, это поле требует корректировки.
## Конфигурация Vite вместо Parcel настроек
Parcel практически не требует конфигурации, тогда как Vite использует `vite.config.js`.
Минимальный конфиг:
```js
import { defineConfig } from 'vite'
export default defineConfig({
server: {
port: 3000
}
})
```
### Alias вместо Parcel resolver
Parcel часто использует:
```json
{
"@components": "./src/components"
}
```
В Vite это переносится через `resolve.alias`:
```js
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
resolve: {
alias: {
'@components': path.resolve(__dirname, 'src/components')
}
}
})
```
## Работа с CSS и препроцессорами
Parcel автоматически включает PostCSS и Sass при обнаружении зависимостей. Vite требует явной установки.
### CSS импорт
Без изменений:
```js
import './styles.css'
```
### Sass
```bash
npm install sass
```
Vite автоматически поддерживает `.scss`, но Parcel-поведение с глобальными стилями может отличаться.
### PostCSS
Если Parcel использовал встроенные плагины, в Vite необходимо добавить:
```js
export default defineConfig({
css: {
postcss: './postcss.config.js'
}
})
```
## Обработка изображений и статических ресурсов
Parcel позволяет импортировать ресурсы без явных правил:
```js
import img from './image.png'
```
Vite сохраняет аналогичное поведение, но различает:
* `public/` — без обработки
* `src/` — через pipeline
### Перенос стратегии ассетов
Parcel:
* все ассеты автоматически обрабатываются
Vite:
* статические файлы в `public/` копируются как есть
* импортируемые файлы проходят через оптимизацию
Пример:
```
public/logo.png → /logo.png (без изменений)
src/logo.png → хешированный импорт
```
## Переменные окружения (.env)
Parcel использует собственные правила экспорта переменных. Vite требует префикса `VITE_`.
### Parcel:
```
API_URL=https://example.com
```
### Vite:
```
VITE_API_URL=https://example.com
```
Использование:
```js
console.log(import.meta.env.VITE_API_URL)
```
Ключевое отличие — отсутствие `process.env` в браузерном контексте Vite.
## Перенос dev-server логики
Parcel запускает dev-server с автоматическим HMR. Vite делает это быстрее за счёт ESM и esbuild.
Основные изменения:
* замена Parcel HMR API на Vite HMR API
* обновление логики accept modules
Пример:
```js
if (import.meta.hot) {
import.meta.hot.accept()
}
```
Parcel-специфичные API (например `module.hot`) требуют замены.
## Работа с TypeScript
Parcel компилирует TypeScript автоматически. Vite также поддерживает TS через esbuild, но без проверки типов.
### Важное отличие:
* Vite не выполняет type-checking по умолчанию
* требуется отдельный процесс:
```bash
tsc --noEmit
```
Parcel-поведение «всё включено» здесь отсутствует.
## Плагины: Parcel vs Vite/Rollup экосистема
Parcel использует собственные трансформеры:
* `@parcel/transformer-babel`
* `@parcel/transformer-postcss`
Vite использует Rollup-плагины:
### Пример замены:
Parcel plugin:
```json
"@parcel/transformer-babel"
```
Vite эквивалент:
```bash
npm install @vitejs/plugin-react
```
```js
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()]
})
```
Ключевая концепция: переход от монолитной системы Parcel к модульной Rollup-экосистеме.
## Различия в production build
Parcel:
```bash
parcel build index.html
```
Vite:
```bash
vite build
```
Vite использует Rollup внутри, что влияет на:
* tree-shaking
* code splitting
* chunking стратегии
Parcel чаще генерирует более «агрессивно объединённые» бандлы, Vite — более управляемые чанки.
## Code splitting и динамические импорты
Parcel и Vite поддерживают:
```js
const module = await import('./module.js')
```
Но различия:
* Parcel автоматически оптимизирует split points
* Vite требует более явного контроля через Rollup options при необходимости
## Частые проблемы при миграции
### 1. Неправильные пути ассетов
Parcel:
```js
import img from './assets/img.png'
```
Vite:
* может требовать `/src/assets` или `public/`
### 2. process.env ошибки
Parcel допускает:
```js
process.env.API_URL
```
Vite требует:
```js
import.meta.env.VITE_API_URL
```
### 3. CommonJS зависимости
Vite в ESM-режиме может требовать:
* оптимизации через `optimizeDeps`
* замены require/import
## Оптимизация после миграции
После перехода на Vite обычно выполняется:
### 1. Оптимизация pre-bundling
```js
export default defineConfig({
optimizeDeps: {
include: ['lodash']
}
})
```
### 2. Настройка build target
```js
build: {
target: 'es2018'
}
```
### 3. Разделение чанков
```js
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom']
}
}
}
}
```
## Итоговая модель миграции Parcel → Vite
Переход представляет собой не простую замену инструмента, а смену архитектурной модели:
* от автоматического пайплайна к модульной системе
* от скрытой конфигурации к явной
* от глобальной обработки графа к ESM-ориентированной модели
* от встроенных трансформеров к Rollup-плагинам
Основная сложность миграции заключается не в синтаксисе, а в выявлении неявных механизмов Parcel и их явной репликации в Vite-конфигурации.