Совместимость форматов с различными средами выполнения

esbuild генерирует выходные артефакты в нескольких форматах модулей, каждый из которых ориентирован на конкретные среды выполнения JavaScript. Ключевая особенность подхода заключается в том, что один и тот же исходный код может быть преобразован в разные представления без изменения логики приложения, но с учётом ограничений платформы.

ESM (ECMAScript Modules)

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

Особенности:

  • Поддержка статического анализа импортов и экспортов
  • Асинхронная загрузка модулей
  • Совместимость с современными браузерами и Node.js (в режиме ESM)
  • Возможность tree-shaking на уровне сборки

В esbuild формат ESM активируется через:

  • format: "esm"

Типичный результат включает строгие import/export конструкции:

import { fn } from './module.js';
export const value = 42;

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


CommonJS (CJS)

CommonJS остаётся ключевым форматом в экосистеме Node.js, особенно в старых проектах и библиотеках.

Особенности:

  • Синхронная система модулей
  • Использование require() и module.exports
  • Широкая совместимость с Node.js без дополнительных настроек

В esbuild активируется через:

  • format: "cjs"

Пример выходного кода:

const { fn } = require('./module.js');
exports.value = 42;

CommonJS часто используется как fallback-формат для совместимости.


IIFE (Immediately Invoked Function Expression)

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

Особенности:

  • Отсутствие системы импортов
  • Немедленное выполнение кода
  • Подходит для CDN и простого подключения через <script>

В esbuild:

  • format: "iife"

Пример структуры:

(() => {
  const value = 42;
  window.myLibrary = { value };
})();

IIFE часто используется для библиотек, распространяемых через CDN без сборщиков.


Совместимость с браузерами

Ограничения браузерной среды

Браузеры исторически поддерживают несколько подходов к модулям:

  • ESM через <script type="module">
  • IIFE через обычные <script>
  • UMD (в esbuild напрямую не является основным форматом, но может эмулироваться)

Основная сложность заключается в различии:

  • политики загрузки файлов
  • CORS ограничений
  • необходимости явного указания путей

Оптимизация под браузер

При сборке под браузер используются параметры:

  • platform: "browser"
  • target: "es2017" или выше

Это влияет на:

  • трансформацию синтаксиса
  • полифиллы (или их отсутствие)
  • формат вывода

Совместимость с Node.js

Node.js поддерживает два основных режима:

CommonJS режим

По умолчанию Node.js интерпретирует файлы как CommonJS. Поэтому:

  • используется require
  • расширение .js без type: module

ESM режим

При наличии:

{
  "type": "module"
}

Node.js переключается на ESM поведение.

esbuild учитывает это при сборке через:

  • platform: "node"

Особенности Node.js-ориентированной сборки:

  • сохранение __dirname через polyfill или исключение
  • корректная обработка import.meta.url
  • поддержка встроенных модулей (fs, path)

Deno и особенности ESM-ориентированных сред

Deno использует исключительно ESM-стиль модулей.

Особенности совместимости:

  • отсутствие CommonJS
  • обязательные URL-импорты (в некоторых сценариях)
  • строгая модель разрешений

При сборке:

  • format: "esm"
  • platform: "neutral" или "browser"

Deno требует:

  • минимизации Node-specific API
  • исключения встроенных Node модулей

Bun и гибридная совместимость

Bun поддерживает:

  • ESM
  • CommonJS
  • гибридное выполнение

Однако поведение отличается:

  • более агрессивная оптимизация
  • встроенный bundler может конфликтовать с внешней сборкой

При использовании esbuild важно:

  • избегать двойной бандлизации
  • согласовывать target с Bun runtime

Workers (Cloudflare и аналогичные среды)

Среды выполнения типа Workers поддерживают:

  • ESM как основной формат
  • ограниченный доступ к Node API

Требования:

  • отсутствие fs, net
  • использование Web API вместо Node API

Сборка через esbuild:

  • format: "esm"
  • platform: "browser"

Различия платформ в esbuild

Параметр platform

esbuild использует ключевой параметр platform, который определяет стратегию трансформации:

  • browser — оптимизация под веб
  • node — под Node.js окружение
  • neutral — универсальный режим без специфики

Каждый режим влияет на:

  • встроенные polyfills
  • разрешение модулей
  • обработку глобальных объектов

Форматы вывода и их влияние на загрузку

Разделение кода (Code Splitting)

Поддерживается только в ESM:

  • динамические import()
  • автоматическое разделение чанков
  • ленивые загрузки

Минификация и формат

Формат влияет на структуру минифицированного кода:

  • ESM сохраняет импорт/экспорт
  • CJS преобразует их в функции
  • IIFE инкапсулирует весь код

Работа с глобальными переменными

Browser IIFE

Для браузера часто требуется экспорт в глобальный объект:

  • window
  • globalThis

Node.js

Используется:

  • global

esbuild при этом может автоматически адаптировать код, если задан entry point и output format.


Совместимость синтаксиса JavaScript

Транспиляция

esbuild поддерживает быстрый трансформ:

  • ESNext → ES2015+
  • JSX → JavaScript
  • TypeScript → JavaScript

Но формат вывода влияет на результат:

  • CJS требует обёрток функций
  • ESM сохраняет структуру модулей

Встроенные и внешние зависимости

External modules

При сборке под разные среды:

  • Node.js допускает external: ["fs", "path"]
  • браузер требует исключения Node API

Bundle vs external

  • bundle: всё объединяется в один файл
  • external: зависимости остаются импортируемыми

Особенности совместимости при разных target

Параметр target определяет уровень Jav * aScript:

  • es5 — максимальная совместимость
  • es2017 — современный браузерный baseline
  • esnext — минимальная трансформация

Влияние на форматы:

  • старые targets увеличивают размер CJS/IIFE
  • ESM остаётся наиболее компактным

Работа с импортами в разных средах

Node.js

Поддерживаются:

  • локальные файлы
  • node_modules
  • условные экспорты (exports map)

Browser

Поддерживаются:

  • относительные пути
  • URL через CDN

Neutral

Требует:

  • явного указания путей
  • избегания платформенных модулей

Особенности загрузки модулей

ESM загрузка

  • асинхронная
  • граф зависимостей строится заранее

CJS загрузка

  • синхронная
  • выполняется во время исполнения

IIFE

  • отсутствует система модулей
  • весь код выполняется сразу

Влияние формата на производительность

  • ESM: лучше tree-shaking и lazy loading
  • CJS: медленнее анализ зависимостей
  • IIFE: быстрее старт, но без оптимизации модулей

esbuild позволяет минимизировать различия за счёт предварительной оптимизации графа зависимостей до генерации выходного формата.