Типы TypeScript для JS API

TypeScript-типы в JavaScript API esbuild обеспечивают строгую типизацию всех ключевых сущностей сборщика: опций, результатов, сообщений, плагинов и контекстов выполнения. Библиотека поставляется с встроенными декларациями типов, поэтому дополнительная установка @types пакетов не требуется.

Типизация охватывает весь жизненный цикл работы сборщика: от конфигурации build и transform до анализа метаданных и работы с контекстным API.


Встроенные TypeScript декларации esbuild

Пакет esbuild содержит собственные .d.ts файлы, экспортирующие основные интерфейсы:

  • BuildOptions
  • TransformOptions
  • BuildResult
  • TransformResult
  • Metafile
  • Message
  • Plugin
  • Loader
  • Platform
  • Format
  • Target

Типы импортируются напрямую из основного пакета:

import { build, transform, BuildOptions, TransformOptions } from "esbuild";

Тип BuildOptions

BuildOptions описывает конфигурацию сборки. Это один из самых объёмных типов в API, содержащий десятки параметров.

Ключевые группы полей:

Входные данные

interface BuildOptions {
  entryPoints?: string[] | { [name: string]: string };
  stdin?: StdinOptions;
  bundle?: boolean;
}
  • entryPoints — список входных файлов
  • stdin — виртуальный вход
  • bundle — включает бандлинг зависимостей

Выходные параметры

outdir?: string;
outfile?: string;
write?: boolean;
format?: "iife" | "cjs" | "esm";
  • outdir — директория вывода
  • outfile — единый файл вывода
  • write — запись на диск или возврат в память
  • format — формат модуля

Платформа и цель

platform?: "node" | "browser" | "neutral";
target?: string | string[];
  • platform влияет на встроенные полифилы и поведение резолвинга
  • target определяет версию ECMAScript

Лоадеры и резолвинг

loader?: {
  [ext: string]: Loader;
};

Loader — строго типизированное объединение:

type Loader =
  | "js"
  | "jsx"
  | "ts"
  | "tsx"
  | "json"
  | "text"
  | "binary"
  | "base64"
  | "css"
  | "file";

Система плагинов

plugins?: Plugin[];

Тип Plugin строго описывает структуру расширений:

interface Plugin {
  name: string;
  setup(build: PluginBuild): void | Promise<void>;
}

Тип TransformOptions

TransformOptions используется для преобразования отдельных файлов без бандлинга.

import { transform, TransformOptions } from "esbuild";

Основные поля

interface TransformOptions {
  loader?: Loader;
  format?: "iife" | "cjs" | "esm";
  target?: string | string[];
  sourcemap?: boolean | "inline" | "external";
}

Особенность типизации transform

Результат строго связан с входными параметрами:

const result = await transform("const x: number = 1", {
  loader: "ts",
});

Тип результата:

interface TransformResult {
  code: string;
  map?: string;
  warnings: Message[];
}

Тип BuildResult

Результат build() содержит как выходные файлы, так и диагностическую информацию.

interface BuildResult<OutputFile extends boolean = boolean> {
  errors: Message[];
  warnings: Message[];
  metafile?: Metafile;
  outputFiles?: OutputFile extends true ? OutputFileData[] : never;
}

Message — структура ошибок и предупреждений

interface Message {
  text: string;
  location?: {
    file: string;
    line: number;
    column: number;
  };
  detail?: any;
}

Тип Message используется как для ошибок, так и для предупреждений, что упрощает унификацию обработки диагностик.


Metafile и его типизация

Metafile — структурированное описание графа модулей.

interface Metafile {
  inputs: {
    [path: string]: {
      bytes: number;
      imports: ImportRecord[];
    };
  };
}

ImportRecord

interface ImportRecord {
  path: string;
  kind: "import-statement" | "require-call" | "dynamic-import";
}

Metafile активно используется для анализа зависимостей и построения графов сборки.


Типизация Loader и форматирования модулей

Format

type Format = "iife" | "cjs" | "esm";
  • iife — самовызывающаяся функция
  • cjs — CommonJS
  • esm — ES Modules

Platform

type Platform = "browser" | "node" | "neutral";

Тип влияет на:

  • вставку глобальных переменных
  • резолвинг встроенных модулей
  • оптимизацию вывода

Context API и его типизация

Context API добавляет поддержку долгоживущих сборок и инкрементальной компиляции.

import { context } from "esbuild";

ContextOptions

Основан на BuildOptions, но расширен:

interface ContextOptions extends BuildOptions {
  incremental?: boolean;
}

Context тип

interface Context {
  rebuild(): Promise<BuildResult>;
  watch(): Promise<void>;
  dispose(): Promise<void>;
}

Контекст используется для:

  • watch-режима
  • ускоренных пересборок
  • управления жизненным циклом сборки

Инкрементальные сборки и типизация

Инкрементальные сборки связаны с расширением BuildResult:

interface BuildResult {
  rebuild?: () => Promise<BuildResult>;
  dispose?: () => void;
}

Типизация отражает возможность повторного использования кеша между сборками.


Типы плагинов и PluginBuild

PluginBuild

interface PluginBuild {
  onResolve(options: OnResolveOptions, callback: OnResolveCallback): void;
  onLoad(options: OnLoadOptions, callback: OnLoadCallback): void;
}

OnResolveOptions

interface OnResolveOptions {
  filter: RegExp;
  namespace?: string;
}

OnLoadOptions

interface OnLoadOptions {
  filter: RegExp;
  namespace?: string;
}

Результаты обработчиков

interface OnResolveResult {
  path: string;
  namespace?: string;
}

interface OnLoadResult {
  contents: string;
  loader: Loader;
}

Generic-типы и расширение API

Некоторые части API используют дженерики для более точного вывода типов.

BuildResult с выводом outputFiles

const result = await build({
  write: false,
  entryPoints: ["index.ts"],
});

Если write: false, TypeScript выводит наличие outputFiles:

result.outputFiles?.forEach(file => {
  console.log(file.path);
});

Типизация stdin входа

interface StdinOptions {
  contents: string;
  loader?: Loader;
  resolveDir?: string;
}

Используется для виртуальных сборок без файловой системы.


Вспомогательные типы API

Charset и source map режимы

type Sourcemap = boolean | "inline" | "external";

Watch режим

interface WatchOptions {
  onRebuild?: (error: Error | null, result: BuildResult) => void;
}

Особенности строгой типизации esbuild

  • отсутствуют any в публичных интерфейсах
  • большинство строковых параметров представлены union-типами
  • плагины строго типизированы через PluginBuild
  • результаты сборки зависят от входных опций
  • поддерживается частичная выводимость типов в build() и transform()

Пример полной типизированной сборки

import { build, BuildOptions, BuildResult } from "esbuild";

const options: BuildOptions = {
  entryPoints: ["src/index.ts"],
  bundle: true,
  platform: "node",
  format: "cjs",
  sourcemap: true,
  write: false,
};

const result: BuildResult = await build(options);

result.errors.forEach(err => {
  console.log(err.text);
});

Пример типизированного transform

import { transform, TransformOptions, TransformResult } from "esbuild";

const options: TransformOptions = {
  loader: "ts",
  sourcemap: true,
};

const result: TransformResult = await transform(
  "const x: number = 10;",
  options
);

Типобезопасность плагинов

import { Plugin } from "esbuild";

const myPlugin: Plugin = {
  name: "example",
  setup(build) {
    build.onResolve({ filter: /.*/ }, args => {
      return { path: args.path };
    });

    build.onLoad({ filter: /.*/ }, args => {
      return {
        contents: "export const x = 1;",
        loader: "js",
      };
    });
  },
};