Parcel построен вокруг концепции инкрементального графа
зависимостей, где каждый модуль проекта рассматривается как
узел, а связи import / require формируют рёбра
графа. В отличие от классических бандлеров, где сборка часто
представляет собой линейный процесс, здесь основной акцент сделан на
динамическом построении, кешировании и переиспользовании
графа.
Архитектура делится на несколько ключевых подсистем:
Каждая из этих частей работает как отдельный слой, но все они связаны через единый объект графа, который является центральной структурой всей системы.
Основная сущность, с которой работает Parcel, — это граф зависимостей (Dependency Graph).
Он состоит из:
Каждый узел графа содержит:
Граф строится лениво: Parcel не пытается сразу обработать весь проект, а начинает с entry-point и постепенно расширяет граф по мере обнаружения импортов.
Процесс начинается с точки входа (entry file). Далее выполняется рекурсивный обход:
На каждом шаге Parcel работает не с текстом, а с AST (Abstract Syntax Tree), что позволяет точно определять зависимости без использования строкового анализа.
Parcel не просто строит дерево зависимостей — он строит граф, поскольку:
Система резолвинга отвечает за преобразование строковых импортов в реальные файлы.
Пример:
import Button from "./components/Button";
Parcel выполняет несколько шагов:
.js, .ts,
.jsx, .json)index файлов в директорияхРезолвер в Parcel является расширяемым и может учитывать:
Результат резолвинга — это уникальный идентификатор ассета, который затем используется в графе.
После того как модуль добавлен в граф, он проходит через систему трансформаций.
Transformer Pipeline работает как цепочка этапов:
Примеры трансформаций:
Каждый трансформер возвращает:
Это критически важно: трансформации могут изменять структуру графа, добавляя новые узлы.
Граф в Parcel не является статическим. Он может изменяться в процессе трансформаций.
Сценарий:
A.js импортирует B.cssurl(image.png)image.pngТаким образом, граф зависит не только от JS-импортов, но и от внутреннего анализа всех типов ресурсов.
Parcel активно использует кеширование на уровне узлов графа.
Кеш включает:
Если файл не изменился, Parcel:
Это делает возможным:
Кеш связан напрямую с графом: каждый узел знает, валиден ли его результат.
При изменении файла Parcel не пересобирает всё дерево, а выполняет локальную инвалидацию:
Если изменение касается модуля, используемого в нескольких местах, обновляются только связанные ветки графа, а не весь проект.
Parcel использует многопоточную модель выполнения:
Scheduler распределяет задачи по типу:
Граф при этом выступает как источник задач: каждый узел может генерировать новые задания.
После построения полного графа начинается этап упаковки.
Graph → Bundles transformation включает:
Parcel использует граф для принятия решений:
Разбиение кода происходит автоматически на основе структуры графа.
Основные стратегии:
import())Если модуль встречается в нескольких ветках графа, он выносится в общий chunk.
Граф зависимостей в реальных проектах часто содержит циклы:
A → B → C → A
Parcel обрабатывает их через:
Циклы не ломают граф, а становятся частью его структуры.
Parcel работает не только с JS, но и с универсальными asset nodes:
Каждый тип ассета является узлом одного графа, что делает систему унифицированной мультимодульной структурой.
Каждый узел графа содержит метаданные:
Эти данные используются для:
Архитектура Parcel вокруг графа выглядит как конвейер:
Все процессы замкнуты на одну структуру — dependency graph, который является центральной моделью всей системы сборки.