Parcel предоставляет программный API, позволяющий управлять процессом сборки напрямую из Node.js-кода без использования CLI. Этот подход применяется в сценариях, где требуется динамическая конфигурация сборки, интеграция с серверными процессами, кастомные пайплайны или запуск bundling как части более крупной системы.
Программный интерфейс Parcel построен вокруг нескольких ключевых сущностей:
В современных версиях Parcel основным объектом является
Parcel, который объединяет функциональность компиляции и
наблюдения за изменениями.
Программный API начинается с инициализации компилятора через
конструктор Parcel.
import { Parcel } from "@parcel/core";
const bundler = new Parcel({
entries: "src/index.html",
defaultConfig: "@parcel/config-default",
mode: "development",
shouldDisableCache: false,
hmrOptions: {
port: 1234
}
});
Ключевое значение имеет параметр entries. Он определяет
точку входа графа зависимостей. Parcel автоматически анализирует HTML,
JavaScript, CSS и другие ресурсы, строя дерево зависимостей.
Одноразовая сборка выполняется через метод run().
const { bundleGraph, buildTime } = await bundler.run();
bundleGraph.getBundles().forEach(bundle => {
console.log(bundle.filePath);
});
console.log(`Build completed in ${buildTime}ms`);
Метод run() инициирует полный цикл:
Результатом является BundleGraph, который отражает
структуру финальной сборки.
BundleGraph — центральная структура данных, описывающая
результат компиляции.
Основные операции:
const bundles = bundleGraph.getBundles();
const entryBundles = bundleGraph.getEntryBundles();
const childBundles = bundleGraph.getChildBundles(bundle);
Каждый bundle содержит:
Граф позволяет анализировать структуру сборки без обращения к файловой системе.
Для разработки используется watch-режим:
const subscription = await bundler.watch((err, event) => {
if (err) {
console.error(err);
return;
}
if (event.type === "buildSuccess") {
const bundles = event.bundleGraph.getBundles();
bundles.forEach(b => console.log("Updated:", b.filePath));
}
if (event.type === "buildFailure") {
console.error(event.diagnostics);
}
});
Watch API реализует непрерывный цикл сборки. При изменении файлов Parcel пересчитывает только затронутые части графа, используя инкрементальную модель.
Одной из ключевых особенностей программного API является кэширование на уровне модулей.
Каждый модуль имеет:
При изменении файла Parcel сравнивает хеши и пересобирает только затронутые узлы графа, минимизируя время пересборки.
В отличие от CLI, программный API позволяет динамически изменять конфигурацию:
const bundler = new Parcel({
entries,
mode: process.env.NODE_ENV,
targets: {
main: {
context: "browser",
distDir: "./dist",
sourceMap: true
}
}
});
Параметр targets управляет выходными артефактами. Можно
определить несколько целей сборки с разными настройками.
Ассеты в Parcel представляют собой абстракцию файлов.
const assets = bundle.getAssets();
assets.forEach(asset => {
console.log(asset.type);
console.log(asset.filePath);
});
Каждый asset проходит цепочку трансформаций:
Эта цепочка может быть расширена через плагины.
Программный API позволяет встраивать Parcel в собственные системы сборки:
async function buildProject() {
const bundler = new Parcel({
entries: "./src/index.html",
});
const { bundleGraph } = await bundler.run();
const bundles = bundleGraph.getBundles();
return bundles.map(b => ({
path: b.filePath,
size: b.stats?.size
}));
}
Такой подход используется в серверных приложениях, CI/CD и автоматизированных системах деплоя.
Parcel возвращает структурированные диагностические сообщения:
if (event.type === "buildFailure") {
event.diagnostics.forEach(d => {
console.log(d.message);
console.log(d.hints);
console.log(d.codeFrames);
});
}
Диагностика включает:
HMR интегрирован в watch-режим и доступен через события сборки:
if (event.type === "buildSuccess") {
if (event.changedAssets.length > 0) {
console.log("HMR updates available");
}
}
Parcel формирует HMR-граф, определяя минимальный набор модулей, требующих обновления без перезагрузки страницы.
Программный API тесно связан с системой плагинов. Плагины могут вмешиваться в:
Пример подключения кастомного конфигурационного плагина:
new Parcel({
entries: "src/index.html",
defaultConfig: "@parcel/config-default"
});
Плагины подключаются через конфигурацию и влияют на весь граф компиляции.
Экземпляр Parcel поддерживает явное завершение работы:
const watcher = await bundler.watch(callback);
// завершение
await watcher.unsubscribe();
Это важно для серверных приложений, где утечки наблюдателей приводят к росту потребления памяти.
Parcel использует многопоточную архитектуру:
Программный API не требует ручного управления потоками, но поведение можно косвенно контролировать через конфигурацию кэша и targets.
Parcel абстрагирует доступ к файлам через собственный FS-слой:
Это позволяет запускать сборку в нестандартных окружениях, включая in-memory FS или контейнеры CI.
Типичный сценарий — интеграция с Node.js сервером:
import express from "express";
import { Parcel } from "@parcel/core";
const app = express();
const bundler = new Parcel({
entries: "./src/index.html"
});
app.get("/build", async (req, res) => {
const { bundleGraph } = await bundler.run();
res.json(
bundleGraph.getBundles().map(b => b.filePath)
);
});
app.listen(3000);
Такой подход позволяет динамически инициировать сборку по запросу.
Parcel предоставляет доступ к статистике сборки:
const { buildTime, inputCount, totalAssetSize } = await bundler.run();
console.log(buildTime);
Эти данные используются для оптимизации пайплайнов и выявления узких мест в проекте.