Резолюция модулей в Parcel основана на сочетании алгоритмов Node.js,
анализе метаданных пакетов и собственных оптимизаций бандлера. В
процессе сборки каждый импорт проходит несколько стадий: нормализацию
пути, определение типа модуля, поиск физического файла, интерпретацию
package.json и применение правил трансформации.
Ключевая особенность Parcel заключается в том, что резолюция выполняется не единожды, а повторяется в разных контекстах графа зависимостей. Это означает, что одна и та же строка импорта может интерпретироваться по-разному в зависимости от окружения, типа сборки (development/production) и активных трансформеров.
Первый шаг — приведение строки импорта к каноническому виду:
./, ../)file:)Особое значение имеет различие между:
./utils/mathreact,
lodash/debounce@app/utilsParcel не интерпретирует алиасы напрямую — они разрешаются через конфигурацию и плагины резолвера.
После нормализации запускается поиск кандидатов:
Проверка наличия файла с указанным именем
Попытка добавления расширений:
.js.jsx.ts.tsx.jsonПроверка директорий с index-файлами
Алгоритм аналогичен Node.js, но дополнен поддержкой трансформеров, которые могут подменять итоговый файл до его фиксации в графе.
Если импорт указывает на пакет, Parcel анализирует
package.json:
main — классическая точка входаmodule — ESM-версияsource — исходный вход для трансформацийexports — современная схема экспортаbrowser — браузерные подменыОсобое внимание уделяется полю exports, которое может
полностью изменить маршрут резолюции:
{
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
}
}
В этом случае прямой доступ к внутренним файлам пакета блокируется, и Parcel обязан следовать декларативной карте экспортов.
Одна из частых причин ошибок — смешивание модулей:
import/exportrequire/module.exportsParcel пытается автоматически адаптировать формат, но при конфликте типов может возникать:
Cannot find moduleПри наличии нескольких файлов:
utils.js
utils.ts
utils/index.js
результат резолюции зависит от порядка приоритетов расширений. В Parcel он определяется конфигурацией и внутренним списком предпочтений. Ошибки возникают, когда:
Monorepo-структуры часто используют символические ссылки. Parcel по умолчанию может:
Это влияет на:
Неправильная интерпретация symlink приводит к ситуации, когда один и тот же модуль загружается дважды в разных контекстах графа.
Parcel предоставляет детализированные логи резолюции. При увеличении уровня логирования становятся видны:
Полезные режимы:
--log-level verbose--log-level infoВ verbose-режиме отображается полный путь принятия решений резолвера.
Граф модулей — основной инструмент диагностики. Он позволяет увидеть:
В графе особенно важно отслеживать:
exportsParcel активно использует кеширование:
Проблемы кеша проявляются как:
Диагностика включает:
.parcel-cacheParcel поддерживает алиасы через:
package.json (поле alias)tsconfig.json (compilerOptions.paths)Конфликты возникают при:
Пример проблемного случая:
{
"paths": {
"@/*": ["src/*"],
"@utils/*": ["src/utils/*"]
}
}
Если одновременно используется alias @/utils, резолвер
может выбрать неоднозначный маршрут.
Современные пакеты используют условные экспорты:
importrequirebrowserdefaultParcel выбирает ветку в зависимости от контекста сборки. Ошибки возникают, если:
requirebrowserimport() добавляет дополнительный слой сложности. Parcel
должен:
Проблемы диагностики:
Трансформеры (Babel, TypeScript, PostHTML) могут изменять:
Особенно критично:
Резолюция в Parcel происходит до и после трансформации, что создаёт два слоя анализа:
Несоответствие между ними часто становится причиной трудноуловимых ошибок.
Причины:
Последствия:
Parcel способен обнаруживать циклы, но резолюция внутри цикла может привести к:
undefined экспортамПакеты с некорректным exports могут приводить к:
Для понимания поведения резолвера полезно рассматривать его как конечный автомат:
Каждое изменение конфигурации меняет набор переходов, а значит — итоговый граф зависимостей.
Если Parcel сталкивается с несколькими кандидатами, применяется приоритет:
exportsmodulemainindex-файлыНарушение этого порядка обычно сигнализирует о: