Выход Parcel v2 стал крупнейшим обновлением в истории инструмента. Если Parcel v1 был ориентирован на максимально простой запуск проектов без настройки, то вторая версия сохранила философию «zero configuration», одновременно полностью переработав внутреннюю архитектуру.
Основные цели разработки Parcel v2:
Переход с первой версии требует понимания ряда архитектурных изменений, поскольку многие внутренние механизмы были реализованы заново.
Parcel v2 фактически представляет собой новый инструмент с точки зрения внутреннего устройства.
Среди наиболее значимых изменений:
| Возможность | Parcel v1 | Parcel v2 |
|---|---|---|
| Система плагинов | Ограниченная | Полностью переработанная |
| Кеширование | Базовое | Продвинутое |
| Поддержка монорепозиториев | Частичная | Полноценная |
| Scope Hoisting | Ограниченное | Улучшенное |
| Tree Shaking | Базовое | Улучшенное |
| Поддержка TypeScript | Есть | Улучшена |
| Поддержка Web Workers | Частичная | Расширена |
| Поддержка целей сборки | Ограниченная | Полноценная |
Многие настройки, ранее задававшиеся через CLI-флаги, теперь описываются в конфигурационных файлах проекта.
В большинстве проектов использовался пакет:
npm install parcel-bundler --save-dev
или
yarn add parcel-bundler -D
Пакет был переименован:
npm install parcel --save-dev
или
yarn add parcel -D
Старый пакет parcel-bundler больше не используется.
Часто встречался следующий вариант:
{
"scripts": {
"start": "parcel src/index.html",
"build": "parcel build src/index.html"
}
}
Во многих случаях такая конфигурация продолжает работать и после обновления.
Однако рекомендуется учитывать новые возможности системы целей сборки.
Одно из наиболее важных нововведений 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 отвечает за преобразование файлов:
module.exports = new Transformer({
async transform({ asset }) {
return [asset];
}
});
Подобная архитектура позволяет изменять практически любой этап сборки.
Parcel автоматически использовал Babel при наличии конфигурации:
{
"presets": ["@babel/preset-env"]
}
Поведение осталось похожим, однако появилась более тесная интеграция с системой кеширования.
Файл конфигурации может выглядеть следующим образом:
{
"presets": [
[
"@babel/preset-env",
{
"targets": "> 0.25%, not dead"
}
]
]
}
Parcel v2 автоматически отслеживает изменения конфигурации Babel и корректно инвалидирует кеш.
Типичная структура:
src/
└─ index.ts
Команда сборки:
parcel src/index.ts
Базовый сценарий практически не изменился:
parcel src/index.ts
Однако появились улучшения:
Конфигурация:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext"
}
}
полностью поддерживается без дополнительной настройки.
Parcel v2 значительно улучшил CSS-пайплайн.
Поддерживаются:
Пример 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 получил улучшенную систему оптимизации изображений.
Поддерживаются:
Импорт изображения:
import logo from "./logo.png";
const img = document.createElement("img");
img.src = logo;
Во время сборки автоматически выполняются:
Использовался специальный синтаксис:
const worker = new Worker("worker.js");
Поддержка стала значительно надежнее:
const worker = new Worker(
new URL("./worker.js", import.meta.url)
);
Такой подход соответствует современным стандартам JavaScript.
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.
Parcel v2 эффективнее удаляет неиспользуемый код.
Пример:
export function used() {
return 1;
}
export function unused() {
return 2;
}
Импорт:
import { used } from "./utils";
После сборки функция unused() будет удалена из итогового
бандла при соблюдении условий статического анализа.
Scope Hoisting объединяет модули в единый граф исполнения.
В Parcel v1 эта технология работала не во всех сценариях.
Parcel v2 использует более агрессивную оптимизацию:
Для большинства проектов настройка не требуется.
Во второй версии улучшена генерация карт исходного кода.
Настройка:
{
"targets": {
"default": {
"sourceMap": true
}
}
}
или
{
"targets": {
"default": {
"sourceMap": {
"inline": false
}
}
}
}
Поддерживаются:
Использование:
process.env.API_URL
Подход сохранился:
console.log(process.env.API_URL);
Файл:
.env
Пример:
API_URL=https://api.example.com
Поддерживаются:
.env;.env.local;.env.production;.env.development.Запуск разработки:
parcel src/index.html
Сборка:
parcel build src/index.html
Разработка:
parcel serve src/index.html
или
parcel src/index.html
Сборка:
parcel build src/index.html
Отдельная команда serve делает намерение разработчика
более явным.
Наиболее частая проблема — несовместимость расширений.
Например:
parcel-plugin-*
Многие плагины первой версии требуют полной замены аналогами для Parcel v2.
После миграции могут возникать ошибки:
Cannot find Babel config
или
Unknown Babel plugin
Необходимо проверить:
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
parcel-bundler до
parcel..parcel-cache.targets..parcelrc.Такой порядок позволяет поэтапно выявлять несовместимости и использовать все преимущества новой архитектуры Parcel v2.