Разрешение модулей в esbuild начинается с анализа значения
import или require и определения типа пути:
абсолютный, относительный или пакетный. От этого зависит дальнейшая
стратегия поиска ресурса и набор применяемых правил.
Первичный этап — определение формы спецификатора:
./,
../) — интерпретируются относительно файла, в котором
происходит импорт./) — обрабатываются
через корневую файловую систему или виртуальные корни, заданные
плагинами.react,
lodash/debounce) — проходят через систему поиска
node_modules.Каждый тип запускает отдельную ветку алгоритма разрешения.
Для относительных и абсолютных путей применяется последовательная стратегия проверки:
Проверка точного совпадения файла.
Попытка добавления расширений в порядке приоритета:
.tsx.ts.jsx.js.json.css (при включённых соответствующих loader-ах)Проверка директорий:
index файлов внутри папки (index.js,
index.ts и т.д.)Этот этап выполняется до обращения к системе пакетов, если путь не является package import.
Порядок расширений в esbuild имеет значение только при неоднозначности. Если существует несколько файлов с одинаковым базовым именем, выбирается первый совпавший вариант согласно внутреннему списку loader-ов и активных настроек сборки.
Ключевой момент: esbuild не использует глобальную систему расширений
Node.js, а опирается на конфигурацию сборки (loader,
resolveExtensions через плагины).
При пакетных импортах запускается поиск по дереву директорий:
node_modules/<package>.Дальнейшее разрешение зависит от содержимого
package.json.
esbuild анализирует метаданные пакета для определения точки входа.
Приоритет зависит от режима сборки (platform,
format, conditions):
Основные поля:
exports — имеет наивысший приоритет
при наличии.module — используется для
ESM-сборок.main — fallback для CommonJS.browser — переопределяет поведение в
браузерном режиме.Если присутствует exports, остальные поля часто
игнорируются, за исключением специальных случаев условий экспорта.
Поле exports представляет собой дерево условий:
Проверка точного совпадения подпути (".",
"./subpath").
Последовательная проверка условий:
importrequiredefaultbrowser, node,
production)Выбор происходит по первому совпавшему условию, соответствующему текущему контексту сборки.
Если условие ведёт к строке — выполняется повторное разрешение пути.
esbuild учитывает контекст сборки:
platform: browser влияет на выбор
browser-полей.platform: node отключает некоторые браузерные
подмены.format: esm/cjs/iife влияет на интерпретацию
module и main.Эти параметры изменяют приоритеты без изменения самого алгоритма обхода.
Если импорт указывает на пакет без конкретного файла:
exports["."]main или moduleindex.js как fallbackДиректория считается валидной точкой входа только при наличии одного из этих элементов.
Импорты вида package/subpath обрабатываются через:
exports.node_modules/package/subpath.Если exports присутствует и не содержит соответствующего
подпути, прямой доступ блокируется.
Ключевое отличие esbuild от классического Node resolution — наличие системы плагинов.
Плагины могут:
onResolve)При этом порядок обработки следующий:
onResolve (в порядке
регистрации).Первый успешный onResolve может полностью остановить
дальнейшее разрешение.
esbuild использует агрессивное кэширование:
результат разрешения пути кешируется по ключу:
повторные импорты не запускают повторный обход дерева
Это существенно ускоряет сборку при больших графах зависимостей.
При обнаружении циклических зависимостей esbuild не изменяет алгоритм разрешения, но фиксирует уже разрешённые пути через кэш, предотвращая повторные вычисления.
Если несколько файлов подходят под одно имя, выбор определяется:
Файлы .ts, .tsx и .jsx
участвуют в разрешении наравне с .js, но:
tsconfig.jsonЭто влияет на этап выбора расширения, но не на общий алгоритм поиска.
Обобщённый порядок разрешения:
onResolve плагиныindexnode_modulespackage.json.exportsmodule / main / browserКаждый следующий шаг выполняется только при отсутствии результата на предыдущем уровне, что формирует детерминированный, но расширяемый механизм разрешения модулей.