В процессе работы сборщика порядок выполнения скриптов определяется
не линейной последовательностью файлов, а графом зависимостей модулей.
Каждый модуль рассматривается как узел, а import и
require формируют рёбра графа. В результате итоговая
последовательность исполнения возникает как результат обхода графа, а не
как отражение физического порядка файлов на диске.
В контексте Esbuild это особенно важно, поскольку сборщик оптимизирует структуру кода, стремясь минимизировать размер бандла и устранить лишние зависимости, одновременно соблюдая семантику ES-модулей.
При запуске сборки Esbuild выполняет несколько этапов:
entryPoints);resolve);onResolve,
onLoad);Каждый импорт рассматривается как потенциальная точка перехода. При этом порядок объявления импортов внутри файла не влияет на порядок исполнения модулей — важна только структура зависимостей.
В ES-модулях используется модель, при которой зависимости инициализируются до выполнения импортирующего модуля. Это приводит к поведению, близкому к post-order обходу:
Esbuild следует этой модели, формируя корректную последовательность инициализации кода в итоговом бандле.
Особое значение имеет механизм live bindings: экспортированные значения не копируются, а связываются через ссылки, поэтому порядок инициализации должен гарантировать доступность этих ссылок до их использования.
Формат бандла напрямую влияет на то, как организуется выполнение кода.
При использовании format: "iife" весь граф модулей
сворачивается в одну функцию. Порядок выполнения становится строго
детерминированным:
Такой формат устраняет динамическую загрузку и фиксирует последовательность исполнения внутри одного синхронного блока.
При format: "cjs" каждый модуль оборачивается в функцию,
а загрузка осуществляется через require. Порядок выполнения
становится ленивым:
require;require.В отличие от ESM, здесь возможны побочные эффекты, зависящие от времени загрузки модулей.
При format: "esm" сохраняется статический характер
графа. Esbuild стремится минимизировать перестановки, оставляя структуру
максимально близкой к исходной спецификации ES Modules. Порядок
исполнения определяется спецификацией ECMAScript, а не самим
сборщиком.
При указании нескольких входных точек:
esbuild app.js admin.js dashboard.js --bundle --outdir=dist
формируется несколько независимых графов зависимостей. При этом:
Ключевой момент заключается в том, что физический порядок файлов в
outdir не является отражением порядка их выполнения в
браузере или Node.js.
При включении:
splitting: true
format: "esm"
Esbuild начинает формировать динамические чанки, загружаемые через
import(). В этом случае порядок выполнения становится
частично асинхронным:
Это приводит к тому, что логическая последовательность кода отделяется от физической структуры файлов.
При использовании metafile: true Esbuild генерирует
структуру вида:
{
"outputs": {
"chunk-A.js": {...},
"chunk-B.js": {...}
}
}
Важно, что outputs — это объект, а не массив,
поэтому:
Реальный порядок выполнения всегда определяется графом зависимостей, а не структурой метафайла.
Плагины Esbuild способны влиять на порядок выполнения косвенно через:
onResolve — изменение маршрутизации импортов;onLoad — подмену содержимого модулей;Порядок регистрации плагинов важен:
onResolve или onLoad
перехватывает обработку;Таким образом, порядок выполнения может быть изменён ещё на этапе построения зависимостей.
Опции:
bannerfooterвлияют на порядок исполнения за счёт добавления кода до и после каждого чанка.
Особенности:
banner выполняется до всех модульных инициализаций
внутри чанка;footer выполняется после завершения исполнения
модуля;Это создаёт предсказуемые точки входа и выхода исполнения внутри каждого файла сборки.
При использовании:
external: ["react"]
модуль исключается из бандла. Это влияет на порядок выполнения следующим образом:
Таким образом, часть графа становится внешней по отношению к Esbuild.
Конструкция:
import("./module.js")
создаёт точку разделения порядка выполнения:
Esbuild преобразует такие конструкции в загрузку чанков, не фиксируя строгого порядка их выполнения относительно синхронного кода.
Несмотря на возможные трансформации, Esbuild сохраняет ключевое свойство ES-модулей — статический анализ импортов. Это означает:
Циклы в графе не ломают порядок выполнения, но вводят промежуточные состояния модулей.
При наличии цикла:
A → B → C → A
Esbuild выполняет частичную инициализацию:
undefined значениями на ранних этапах.Это поведение соответствует спецификации ES Modules и не является особенностью сборщика.
Оптимизации Esbuild включают:
Однако:
Таким образом, оптимизация не ломает логическую последовательность исполнения, но может изменять физическое расположение кода в бандле.
Порядок выполнения скриптов в сборке Esbuild всегда является результатом сочетания нескольких факторов:
Физический порядок файлов, строк в исходном коде или порядок объявления entry points не является определяющим фактором выполнения.