Миграция с Vite

Переход с Vite на Parcel встречается реже, чем обратная миграция, однако существует ряд сценариев, в которых Parcel оказывается более подходящим решением:

  • необходимость минимальной конфигурации;
  • желание сократить количество внешних плагинов;
  • использование монорепозиториев со сложной структурой;
  • предпочтение автоматического определения типов ресурсов;
  • стремление уменьшить объем инфраструктурного кода;
  • потребность в более унифицированной системе сборки для различных типов проектов.

Обе системы относятся к современным инструментам сборки фронтенд-приложений, однако используют разные подходы к разработке и конфигурированию.

Возможность Vite Parcel
Dev-сервер Да Да
HMR Да Да
Конфигурация по умолчанию Минимальная Практически отсутствует
Плагины Rollup-плагины Трансформеры Parcel
Автоматическое определение ресурсов Частично Максимально
Сборка production Rollup Собственный пайплайн
Настройка через конфиг Часто требуется Обычно не требуется

Архитектурные различия

Перед началом миграции важно понимать фундаментальные различия между инструментами.

Архитектура Vite

Во время разработки Vite использует нативные ES-модули браузера:

Исходный код
      ↓
Vite Dev Server
      ↓
ES Modules
      ↓
Браузер

Для production-сборки применяется Rollup:

Исходный код
      ↓
Rollup
      ↓
Bundle

Архитектура Parcel

Parcel использует единый механизм как для разработки, так и для сборки:

Исходный код
      ↓
Parcel Pipeline
      ↓
Трансформеры
      ↓
Бандлы

Благодаря этому многие настройки автоматически работают одинаково во всех режимах.


Анализ существующего проекта

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

package.json

Типичный проект на Vite содержит:

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}

vite.config.js

Основное внимание следует уделить:

  • alias;
  • proxy;
  • плагинам;
  • переменным окружения;
  • настройкам Rollup;
  • настройкам CSS.

Пример:

import { defineConfig } from 'vite';

export default defineConfig({
  resolve: {
    alias: {
      '@': '/src'
    }
  }
});

Каждый элемент конфигурации необходимо проверить на наличие аналога в Parcel.


Установка Parcel

Удаление зависимостей Vite:

npm uninstall vite

или

yarn remove vite

Установка Parcel:

npm install --save-dev parcel

или

yarn add --dev parcel

После установки пакет Parcel становится главным инструментом сборки проекта.


Изменение скриптов package.json

Конфигурация Vite

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}

Конфигурация Parcel

{
  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html"
  }
}

Если точкой входа служит файл в корне проекта:

{
  "scripts": {
    "dev": "parcel index.html",
    "build": "parcel build index.html"
  }
}

Перенос структуры проекта

Типичная структура Vite

project/
├── public/
├── src/
│   ├── assets/
│   ├── components/
│   ├── main.js
│   └── App.jsx
├── index.html
└── vite.config.js

Возможная структура Parcel

project/
├── src/
│   ├── assets/
│   ├── components/
│   ├── main.js
│   └── App.jsx
├── index.html
└── package.json

Во многих случаях файл vite.config.js полностью исчезает.


Миграция alias

Настройка в Vite

resolve: {
  alias: {
    '@': '/src'
  }
}

Импорт:

import Button from '@/components/Button';

Настройка в Parcel

В package.json:

{
  "alias": {
    "@": "./src"
  }
}

После этого импорт остается неизменным:

import Button from '@/components/Button';

Это значительно упрощает миграцию большого количества файлов.


Перенос переменных окружения

Работа с Vite

Файлы:

.env
.env.development
.env.production

Использование:

const apiUrl = import.meta.env.VITE_API_URL;

Работа с Parcel

Файлы:

.env
.env.production
.env.local

Использование:

const apiUrl = process.env.API_URL;

Переменная:

API_URL=https://api.example.com

Одно из самых заметных изменений при миграции — отказ от объекта import.meta.env.


Замена import.meta.env

Было

console.log(import.meta.env.MODE);
console.log(import.meta.env.PROD);
console.log(import.meta.env.DEV);

Стало

console.log(process.env.NODE_ENV);

При необходимости дополнительные значения можно определить самостоятельно:

const isProduction =
  process.env.NODE_ENV === 'production';

Работа со статическими ресурсами

Подход Vite

import logo from './logo.png';
<img src="/logo.png">

Подход Parcel

import logo from './logo.png';
<img src={logo} />

Parcel автоматически анализирует зависимости ресурсов и включает их в граф сборки.


Использование URL-конструкторов

В проектах на Vite часто встречается:

new URL(
  './assets/icon.svg',
  import.meta.url
).href;

В Parcel это обычно не требуется.

Достаточно:

import icon from './assets/icon.svg';
console.log(icon);

Parcel автоматически генерирует корректный путь.


Перенос React-проектов

Vite

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()]
});

Parcel

Для большинства React-проектов дополнительная настройка не нужна:

npm install react react-dom

Файл:

import React from 'react';
import ReactDOM from 'react-dom/client';

ReactDOM.createRoot(
  document.getElementById('root')
).render(
  <App />
);

Parcel самостоятельно определяет JSX и выполняет необходимые преобразования.


Перенос TypeScript

Конфигурация Vite

{
  "compilerOptions": {
    "target": "ES2022"
  }
}

Конфигурация Parcel

Parcel автоматически использует:

tsconfig.json

Например:

{
  "compilerOptions": {
    "strict": true,
    "module": "ESNext"
  }
}

Дополнительные плагины обычно не требуются.


Перенос Sass

Vite

npm install sass
.button {
  color: red;
}

Parcel

npm install sass

Импорт:

import './styles.scss';

Parcel автоматически обнаруживает Sass-файлы и запускает нужный трансформер.


Перенос PostCSS

Конфигурация Vite

export default {
  css: {
    postcss: './postcss.config.js'
  }
};

Конфигурация Parcel

Достаточно оставить:

postcss.config.js

Пример:

module.exports = {
  plugins: {
    autoprefixer: {}
  }
};

Parcel автоматически подключает конфигурацию.


Перенос CSS Modules

Vite

import styles from './Button.module.css';

Parcel

Синтаксис остается тем же:

import styles from './Button.module.css';

Использование:

<button className={styles.button}>
  Click
</button>

Дополнительная настройка отсутствует.


Замена vite.config.js

Одним из главных этапов миграции становится удаление конфигурации Vite.

Конфигурация до миграции

export default defineConfig({
  plugins: [],
  resolve: {},
  server: {},
  build: {}
});

После миграции

Во многих проектах отсутствует какой-либо конфигурационный файл Parcel:

package.json

Parcel старается использовать соглашения вместо конфигурирования.


Перенос прокси-сервера

Vite

server: {
  proxy: {
    '/api': {
      target: 'http://localhost:3000'
    }
  }
}

Parcel

Для подобных сценариев обычно используются:

  • отдельный backend;
  • reverse proxy через Nginx;
  • middleware-сервер;
  • конфигурация окружения.

Прямого аналога настройки из Vite в Parcel нет.


Замена import.meta.glob

Одна из наиболее сложных частей миграции.

Vite

const modules =
  import.meta.glob('./pages/*.js');

Возможные решения в Parcel

Явный импорт:

import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';

Либо генерация списка модулей на этапе сборки сторонними инструментами.

Функциональность автоматического сканирования директорий требует отдельной переработки архитектуры.


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

Плагины Vite

Часто используются:

  • React;
  • Vue;
  • SVG;
  • PWA;
  • MDX;
  • legacy.

Каждый плагин необходимо проверить отдельно.

Например:

npm install vite-plugin-svgr

После перехода обычно заменяется встроенными возможностями Parcel либо специализированными трансформерами.


Работа с SVG

Vite

import Logo from './logo.svg?react';

Parcel

import Logo from './logo.svg';

или

<img src={Logo} />

Способ использования зависит от выбранного трансформера SVG.


Оптимизация production-сборки

Сборка выполняется командой:

npm run build

Parcel автоматически производит:

  • tree shaking;
  • code splitting;
  • минификацию;
  • оптимизацию изображений;
  • удаление неиспользуемого кода;
  • хеширование ресурсов.

Ручная настройка требуется значительно реже по сравнению с экосистемой Rollup.


Проверка миграции

После завершения переноса рекомендуется проверить:

Маршрутизацию

React Router
Vue Router
Angular Router

Загрузку ресурсов

PNG
SVG
WEBP
Fonts
Video
Audio

Переменные окружения

.env
.env.production
.env.local

Code Splitting

const AdminPage = React.lazy(
  () => import('./AdminPage')
);

Production-сборку

npm run build

Dev-режим

npm run dev

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

Использование import.meta.glob

Ошибка:

import.meta.glob is not a function

Причина:

Функция является специфичной для Vite.

Решение:

Переписать механизм загрузки модулей.

Использование import.meta.env

Ошибка:

import.meta.env is undefined

Решение:

process.env.MY_VARIABLE

Зависимость от Rollup-плагинов

Ошибка:

Plugin not found

Причина:

Плагин предназначен только для Rollup/Vite.

Решение:

Найти аналогичный трансформер Parcel.

Пользовательские настройки сборки

Некоторые проекты содержат сложную конфигурацию:

build: {
  rollupOptions: {
    ...
  }
}

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


Рекомендуемая последовательность миграции

  1. Удалить зависимости Vite.
  2. Установить Parcel.
  3. Переписать npm-скрипты.
  4. Настроить alias.
  5. Перенести переменные окружения.
  6. Удалить обращения к import.meta.env.
  7. Проверить работу CSS, Sass и PostCSS.
  8. Перенести обработку SVG.
  9. Переписать код с import.meta.glob.
  10. Удалить vite.config.js.
  11. Выполнить production-сборку.
  12. Проверить маршрутизацию и динамические импорты.
  13. Убедиться в корректной работе оптимизаций и статических ресурсов.

Грамотно выполненная миграция обычно приводит к сокращению объема конфигурационного кода, уменьшению зависимости от специализированных плагинов и более широкому использованию встроенных механизмов Parcel для обработки ресурсов, трансформации исходного кода и оптимизации финальных бандлов.