В esbuild загрузчик (loader) определяет, как конкретный тип файла должен быть интерпретирован и преобразован в процессе сборки. Каждый входной модуль сопоставляется с определённым обработчиком, который решает, будет ли файл трактоваться как JavaScript, JSX, JSON, текст, бинарные данные или другой формат.
Для расширений .js и .jsx используются
встроенные загрузчики, ориентированные на быстрый синтаксический разбор
и минимальные преобразования. Их ключевая особенность — отсутствие
тяжёлой AST-трансформации в привычном смысле: esbuild работает через
высокопроизводительный парсер и генератор кода, оптимизированный на
уровне Go.
Загрузчик js является базовым и применяется ко всем
JavaScript-файлам без JSX-синтаксиса. Он предполагает стандартный
ECMAScript-код, который не содержит JSX-элементов, TypeScript-аннотаций
или других расширений синтаксиса.
Основные характеристики обработки .js:
import и export на уровне
синтаксисаEsbuild рассматривает .js как «почти готовый к
исполнению» формат, где требуется лишь объединение модулей, разрешение
зависимостей и возможная минификация.
Важная особенность заключается в том, что loader js не
выполняет JSX-трансформацию. Любые JSX-конструкции в .js
файле при использовании этого загрузчика приведут к синтаксической
ошибке, если не изменена конфигурация.
При обработке JavaScript-файлов esbuild выполняет несколько стадий:
При этом loader js не добавляет дополнительной семантики
к коду. Он строго следует спецификации ECMAScript и не пытается
интерпретировать расширенные конструкции.
Особенность работы с современным JavaScript заключается в поддержке:
import()Loader jsx предназначен для обработки файлов, содержащих
JSX-синтаксис. JSX представляет собой расширение JavaScript, позволяющее
описывать UI-структуры в декларативной форме.
Основная задача loader jsx — трансформировать
JSX-выражения в вызовы функций JavaScript, которые могут быть выполнены
в стандартной среде выполнения.
Пример исходного JSX-кода:
const element = <div className="box">Hello</div>;
После обработки esbuild:
const element = React.createElement("div", { className: "box" }, "Hello");
или, при использовании автоматического JSX runtime:
import { jsx as _jsx } from "react/jsx-runtime";
const element = _jsx("div", { className: "box", children: "Hello" });
Выбор модели трансформации зависит от параметров конфигурации
jsxFactory, jsxFragment и
jsxRuntime.
Разделение загрузчиков js и jsx основано на
различии в синтаксической допустимости входного кода.
Ключевые отличия:
js не допускает JSX-синтаксисjsx включает дополнительный этап трансформации
JSX-выраженийjs имеет меньшую стоимость обработкиjsx требует генерации дополнительных импортов и вызовов
функцийС точки зрения производительности js является более
лёгким, так как пропускает этап преобразования дерева JSX в вызовы
функций.
Загрузчик задаётся на уровне расширений файлов через конфигурацию bundler-а.
Пример конфигурации:
import * as esbuild from "esbuild";
esbuild.build({
entryPoints: ["src/main.js"],
bundle: true,
outdir: "dist",
loader: {
".js": "js",
".jsx": "jsx"
}
});
В данной конфигурации:
.js файлы обрабатываются как чистый JavaScript.jsx файлы проходят JSX-трансформациюЗагрузчики можно переопределять для любых расширений, однако для
.js и .jsx используются наиболее
оптимизированные встроенные режимы.
В CLI esbuild загрузчики задаются через параметр
--loader:
esbuild src/main.jsx --bundle --outfile=dist/bundle.js --loader:.jsx=jsx
Также возможно указание нескольких загрузчиков:
esbuild src/index.js --bundle \
--loader:.js=js \
--loader:.jsx=jsx
CLI-режим сохраняет ту же семантику, что и API-конфигурация, но предоставляет более компактный способ управления обработкой файлов.
Esbuild поддерживает два основных режима JSX:
/** @jsx React.createElement */
или через конфигурацию:
jsxFactory: "React.createElement",
jsxFragment: "React.Fragment"
В этом режиме каждый JSX-элемент компилируется в вызов функции фабрики.
Современный режим, при котором esbuild автоматически импортирует необходимые функции:
import { jsx } from "react/jsx-runtime";
JSX преобразуется в вызовы _jsx, _jsxs и
аналогичные функции.
Loader jsx не только распознаёт синтаксис, но и
оптимизирует структуру вызовов, минимизируя количество создаваемых
промежуточных объектов.
При трансформации JSX выполняются следующие шаги:
Esbuild избегает глубоких многоступенчатых преобразований AST, что обеспечивает высокую скорость по сравнению с традиционными транспиляторами.
Выбор между js и jsx напрямую влияет на
итоговый размер и структуру бандла:
js приводит к более прямолинейному коду без
дополнительных импортовjsx добавляет runtime-зависимости (например,
react/jsx-runtime)Особенно заметна разница в проектах с большим количеством UI-компонентов, где JSX используется интенсивно.
В рамках одного проекта часто применяется смешанная модель:
.js.jsxПример структуры:
src/
app.js
utils.js
components/
Button.jsx
Modal.jsx
Такой подход позволяет минимизировать избыточную трансформацию и разделить ответственность между слоями приложения.
Если файл содержит синтаксис, не соответствующий выбранному loader, сборка завершается ошибкой.
Типичный случай:
.js содержит JSX → синтаксическая ошибка.jsx содержит недопустимые конструкции → ошибка
парсингаЭто поведение основано на строгой типизации входного синтаксиса, которую esbuild использует для ускорения анализа без попыток «догадок» о намерении разработчика.
Loader js является наиболее быстрым, так как
ограничивается минимальной обработкой синтаксического дерева.
Loader jsx добавляет дополнительный этап трансформации,
но остаётся значительно быстрее аналогичных решений благодаря:
Разница в скорости особенно заметна при больших кодовых базах, где количество JSX-узлов велико.
Выбор между js и jsx определяется
исключительно наличием JSX-синтаксиса:
jsxjsПопытка унифицировать всё под jsx приводит к лишним
трансформациям без практической пользы, тогда как строгая сегрегация
улучшает стабильность и скорость сборки.