Миграция с Parcel v1 на v2

Выход Parcel v2 стал крупнейшим обновлением в истории инструмента. Если Parcel v1 был ориентирован на максимально простой запуск проектов без настройки, то вторая версия сохранила философию «zero configuration», одновременно полностью переработав внутреннюю архитектуру.

Основные цели разработки Parcel v2:

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

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


Ключевые изменения архитектуры

Parcel v2 фактически представляет собой новый инструмент с точки зрения внутреннего устройства.

Среди наиболее значимых изменений:

Возможность Parcel v1 Parcel v2
Система плагинов Ограниченная Полностью переработанная
Кеширование Базовое Продвинутое
Поддержка монорепозиториев Частичная Полноценная
Scope Hoisting Ограниченное Улучшенное
Tree Shaking Базовое Улучшенное
Поддержка TypeScript Есть Улучшена
Поддержка Web Workers Частичная Расширена
Поддержка целей сборки Ограниченная Полноценная

Многие настройки, ранее задававшиеся через CLI-флаги, теперь описываются в конфигурационных файлах проекта.


Установка Parcel v2

Parcel v1

В большинстве проектов использовался пакет:

npm install parcel-bundler --save-dev

или

yarn add parcel-bundler -D

Parcel v2

Пакет был переименован:

npm install parcel --save-dev

или

yarn add parcel -D

Старый пакет parcel-bundler больше не используется.


Обновление package.json

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

Часто встречался следующий вариант:

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

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

Однако рекомендуется учитывать новые возможности системы целей сборки.


Система Targets

Одно из наиболее важных нововведений Parcel v2 — Targets.

Цель сборки описывает конечный результат, который должен получить сборщик.

Пример:

{
  "targets": {
    "main": {
      "sourceMap": true,
      "distDir": "./dist"
    }
  }
}

Теперь один проект может одновременно создавать несколько вариантов сборки:

{
  "targets": {
    "modern": {
      "context": "browser"
    },
    "legacy": {
      "context": "browser"
    }
  }
}

Такой подход особенно полезен при публикации библиотек.


Изменение структуры конфигурации

Parcel v1 практически не требовал конфигурации.

Во второй версии появился специальный файл:

{
  "extends": "@parcel/config-default"
}

Файл называется:

.parcelrc

Он позволяет подключать собственные трансформеры, резолверы, валидаторы и упаковщики.

Пример:

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.md": ["@parcel/transformer-raw"]
  }
}

Новая система плагинов

Parcel v1 поддерживал плагины ограниченно.

Parcel v2 разделил расширения на отдельные категории:

  • Transformer;
  • Resolver;
  • Bundler;
  • Optimizer;
  • Reporter;
  • Validator;
  • Packager;
  • Compressor;
  • Runtime.

Схема работы стала значительно гибче.

Например, Transformer отвечает за преобразование файлов:

module.exports = new Transformer({
  async transform({ asset }) {
    return [asset];
  }
});

Подобная архитектура позволяет изменять практически любой этап сборки.


Изменения в обработке Babel

Parcel v1

Parcel автоматически использовал Babel при наличии конфигурации:

{
  "presets": ["@babel/preset-env"]
}

Parcel v2

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

Файл конфигурации может выглядеть следующим образом:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "> 0.25%, not dead"
      }
    ]
  ]
}

Parcel v2 автоматически отслеживает изменения конфигурации Babel и корректно инвалидирует кеш.


Изменения в поддержке TypeScript

Parcel v1

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

src/
 └─ index.ts

Команда сборки:

parcel src/index.ts

Parcel v2

Базовый сценарий практически не изменился:

parcel src/index.ts

Однако появились улучшения:

  • более быстрое кеширование;
  • лучшая поддержка Project References;
  • улучшенная работа с source maps;
  • корректная обработка современных возможностей TypeScript.

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

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext"
  }
}

полностью поддерживается без дополнительной настройки.


Изменения в обработке CSS

Parcel v2 значительно улучшил CSS-пайплайн.

Поддерживаются:

  • CSS Modules;
  • PostCSS;
  • Sass;
  • Less;
  • Stylus;
  • CSS Nesting;
  • CSS Variables.

Пример CSS Modules:

.title {
  color: red;
}

Импорт:

import styles from "./styles.module.css";

console.log(styles.title);

Механизм генерации классов был переработан и стал более стабильным.


Переход на новую систему кеширования

Одно из крупнейших внутренних изменений связано с кешем.

Parcel v1 использовал относительно простую модель.

Parcel v2 хранит результаты:

  • трансформации файлов;
  • анализа зависимостей;
  • генерации бандлов;
  • оптимизации ресурсов.

Каталог кеша:

.parcel-cache

При возникновении проблем во время миграции часто помогает очистка:

rm -rf .parcel-cache

или

npx parcel cache clear

Изменения в обработке изображений

Parcel v2 получил улучшенную систему оптимизации изображений.

Поддерживаются:

  • PNG;
  • JPEG;
  • GIF;
  • SVG;
  • WebP;
  • AVIF.

Импорт изображения:

import logo from "./logo.png";

const img = document.createElement("img");
img.src = logo;

Во время сборки автоматически выполняются:

  • хеширование файлов;
  • переименование ресурсов;
  • оптимизация;
  • анализ зависимостей.

Изменения в работе с Web Workers

Parcel v1

Использовался специальный синтаксис:

const worker = new Worker("worker.js");

Parcel v2

Поддержка стала значительно надежнее:

const worker = new Worker(
  new URL("./worker.js", import.meta.url)
);

Такой подход соответствует современным стандартам JavaScript.


Поддержка Package Exports

Parcel v2 корректно работает с полем:

{
  "exports": {
    ".": "./dist/index.js"
  }
}

а также со сложными схемами:

{
  "exports": {
    "import": "./dist/module.js",
    "require": "./dist/commonjs.js"
  }
}

Parcel v1 поддерживал подобные сценарии значительно хуже.


Изменения в работе с монорепозиториями

Во второй версии появилась полноценная поддержка монорепозиториев.

Пример структуры:

packages/
 ├─ app
 ├─ ui
 └─ shared

Parcel способен:

  • анализировать зависимости между пакетами;
  • корректно разрешать симлинки;
  • использовать общий кеш;
  • ускорять инкрементальную сборку.

Особенно заметен выигрыш в больших проектах на Yarn Workspaces или npm Workspaces.


Улучшенный Tree Shaking

Parcel v2 эффективнее удаляет неиспользуемый код.

Пример:

export function used() {
  return 1;
}

export function unused() {
  return 2;
}

Импорт:

import { used } from "./utils";

После сборки функция unused() будет удалена из итогового бандла при соблюдении условий статического анализа.


Улучшенный Scope Hoisting

Scope Hoisting объединяет модули в единый граф исполнения.

В Parcel v1 эта технология работала не во всех сценариях.

Parcel v2 использует более агрессивную оптимизацию:

  • уменьшает количество обёрток;
  • снижает размер бандла;
  • ускоряет выполнение приложения.

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


Изменения в Source Maps

Во второй версии улучшена генерация карт исходного кода.

Настройка:

{
  "targets": {
    "default": {
      "sourceMap": true
    }
  }
}

или

{
  "targets": {
    "default": {
      "sourceMap": {
        "inline": false
      }
    }
  }
}

Поддерживаются:

  • внешние карты;
  • встроенные карты;
  • скрытые карты.

Изменения в обработке переменных окружения

Parcel v1

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

process.env.API_URL

Parcel v2

Подход сохранился:

console.log(process.env.API_URL);

Файл:

.env

Пример:

API_URL=https://api.example.com

Поддерживаются:

  • .env;
  • .env.local;
  • .env.production;
  • .env.development.

Обновление команд CLI

Parcel v1

Запуск разработки:

parcel src/index.html

Сборка:

parcel build src/index.html

Parcel v2

Разработка:

parcel serve src/index.html

или

parcel src/index.html

Сборка:

parcel build src/index.html

Отдельная команда serve делает намерение разработчика более явным.


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

Старые плагины

Наиболее частая проблема — несовместимость расширений.

Например:

parcel-plugin-*

Многие плагины первой версии требуют полной замены аналогами для Parcel v2.


Устаревшие конфигурации Babel

После миграции могут возникать ошибки:

Cannot find Babel config

или

Unknown Babel plugin

Необходимо проверить:

  • версии Babel;
  • совместимость пресетов;
  • поддержку используемых плагинов.

Изменение разрешения модулей

Parcel v2 использует более строгие правила резолвинга.

Проблемный импорт:

import helper from "./utils";

Если файл отсутствует:

utils.js

или

utils/index.js

сборка завершится ошибкой.


Ошибки, связанные с кешем

После обновления зависимостей возможны ложные ошибки:

Build failed

или

Cannot resolve dependency

В подобных случаях часто помогает:

rm -rf .parcel-cache

и повторная установка зависимостей:

rm -rf node_modules
npm install

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

  1. Обновить пакет parcel-bundler до parcel.
  2. Удалить устаревшие плагины первой версии.
  3. Очистить каталог .parcel-cache.
  4. Проверить совместимость Babel-конфигурации.
  5. Проверить поддержку TypeScript и PostCSS.
  6. Настроить цели сборки через targets.
  7. При необходимости создать файл .parcelrc.
  8. Выполнить тестовую сборку проекта.
  9. Проверить размер бандлов и производительность.
  10. Провести полное тестирование приложения после перехода.

Такой порядок позволяет поэтапно выявлять несовместимости и использовать все преимущества новой архитектуры Parcel v2.