esbuild поддерживает TypeScript как часть встроенного пайплайна
трансформации, не прибегая к отдельному этапу компиляции через
tsc. Основной принцип работы заключается в удалении типов и
преобразовании синтаксиса в JavaScript без проверки типов.
Файлы с расширениями .ts и .tsx
обрабатываются через встроенный загрузчик ts и
tsx, которые активируются автоматически при указании
соответствующих расширений или явно через конфигурацию
loader.
esbuild выполняет:
type annotations,
interfaces, enums в некоторых режимах);.tsx);При этом проверка типов не выполняется. Это ключевое
архитектурное отличие от tsc. Вся ответственность за
типовую корректность переносится на внешние инструменты или IDE.
Пример результата трансформации:
// input.ts
function sum(a: number, b: number): number {
return a + b;
}
// output.js
function sum(a, b) {
return a + b;
}
Типы полностью удаляются без анализа их корректности.
Несмотря на поддержку синтаксиса, esbuild не реализует полноценный TypeScript-компилятор. Это приводит к ряду ограничений:
type checking);tsconfig-правила, связанные с типами
(например, noImplicitAny);.d.ts;const enums в строгом режиме так, как
это делает tsc.При этом esbuild корректно обрабатывает большинство синтаксических конструкций:
type и interface полностью удаляются;enum преобразуются в JavaScript-объекты;namespace поддерживаются ограниченно и сводятся к
IIFE-структурам.Тип загрузчика определяется либо автоматически, либо явно:
export default {
loader: {
'.ts': 'ts',
'.tsx': 'tsx'
}
}
Встроенные режимы:
ts — для обычных TypeScript-файлов без JSX;tsx — для TypeScript с JSX-разметкой;jsx — для JavaScript с JSX;js — стандартный JavaScript.Loader определяет не только парсинг, но и необходимость JSX-трансформации.
Файлы .tsx представляют собой комбинацию TypeScript и
JSX. При их обработке esbuild выполняет две ключевые операции:
JSX преобразуется в зависимости от конфигурации параметра
jsx.
Параметр jsx определяет стратегию трансформации
JSX-кода.
Доступные значения:
transformpreserveautomaticКлассический режим React 16 и ниже. JSX преобразуется в вызовы функции создания элементов.
jsx: 'transform'
Пример:
const el = <div>Hello</div>;
Преобразуется в:
const el = React.createElement("div", null, "Hello");
Для этого режима часто требуется jsxFactory.
Современный режим React 17+ (новый JSX Transform).
jsx: 'automatic'
JSX преобразуется без необходимости явного импорта React.
const el = <div>Hello</div>;
Результат:
import { jsx as _jsx } from "react/jsx-runtime";
const el = _jsx("div", { children: "Hello" });
Поддерживает оптимизированные runtime-вызовы и tree-shaking.
JSX остаётся нетронутым и передаётся дальше по цепочке инструментов.
jsx: 'preserve'
Используется, если дальнейшую трансформацию выполняет Babel или TypeScript compiler.
При использовании режима transform часто требуется
настройка фабрик JSX.
Определяет функцию создания элементов:
jsxFactory: 'h'
const el = <div />;
Преобразуется в:
const el = h("div", null);
Часто используется в Preact:
jsxFactory: 'h'
Определяет обработчик Fragment:
jsxFragment: 'Fragment'
const el = <>Text</>;
Результат:
const el = Fragment(null, "Text");
Используется в режиме automatic для определения
источника JSX runtime.
jsx: 'automatic',
jsxImportSource: 'preact'
Тогда импорт будет изменён:
import { jsx as _jsx } from "preact/jsx-runtime";
Это позволяет переключаться между React, Preact и другими совместимыми рантаймами без изменения исходного кода.
esbuild не выполняет полноценное чтение tsconfig.json
для компиляции, однако учитывает некоторые параметры через внешние
плагины или ручную настройку.
Игнорируются:
paths (без плагина);baseUrl (без плагина);Частично совместимы:
target (через target esbuild);jsx (через jsx в
esbuild-конфигурации).import { build } from 'esbuild';
build({
entryPoints: ['src/index.tsx'],
bundle: true,
outfile: 'dist/app.js',
target: ['es2018'],
loader: {
'.ts': 'ts',
'.tsx': 'tsx'
},
jsx: 'automatic',
jsxImportSource: 'react'
});
TypeScript-специфичные импорты полностью удаляются:
import type { User } from './types';
После трансформации:
// удалено полностью
Это снижает размер выходного кода и устраняет необходимость дополнительных проходов анализа.
При работе с .tsx важно учитывать:
Пример:
const el = <Component<T> value={42} />;
const el = jsx(Component, { value: 42 });
enum Status {
Active,
Inactive
}
Преобразуется в объект:
var Status;
(function (Status2) {
Status2[Status2["Active"] = 0] = "Active";
Status2[Status2["Inactive"] = 1] = "Inactive";
})(Status || (Status = {}));
namespace Utils {
export function sum(a: number, b: number) {
return a + b;
}
}
Преобразуется в IIFE-структуру с вложенными объектами.
При использовании esbuild важно учитывать концепцию
isolatedModules из TypeScript. Поскольку каждый файл
обрабатывается независимо, конструкции, требующие глобального анализа
типов, могут вести себя иначе, чем в tsc.
Типичные ограничения:
tsc;Процесс трансформации можно представить как последовательность шагов:
Такой подход обеспечивает высокую скорость сборки за счёт отказа от семантического анализа типов и фокусировки исключительно на синтаксической трансформации.