Опция sourcemap: inline, external, linked, both

Опция sourcemap в esbuild управляет тем, как формируются source map-файлы, связывающие итоговый JavaScript-код с исходными файлами. Это критически важно для отладки, поскольку позволяет дебаггеру показывать оригинальный TypeScript или современный JavaScript вместо минифицированного или транспилированного результата.

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


Общий принцип работы source map

Source map — это JSON-структура, которая содержит соответствия между:

  • исходными файлами (sources)
  • позициями в исходном коде
  • позициями в сгенерированном коде

Минимальный результат работы source map — файл .map, который может быть подключён к итоговому JavaScript через директиву:

//# sourceMappingURL=bundle.js.map

или встроен непосредственно в файл.


inline

Режим inline помещает source map непосредственно внутрь итогового JavaScript-файла.

Поведение

  • отдельный .map файл не создаётся
  • карта кодируется в base64
  • добавляется как data URI в конец файла

Пример конфигурации esbuild

import * as esbuild from 'esbuild';

esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  outfile: 'dist/bundle.js',
  sourcemap: 'inline'
});

Как выглядит результат

В конце bundle.js появляется:

//# sourceMappingURL=dat a:application/json;base64,eyJ2ZXJzaW9uIjo...

Особенности

  • увеличивает размер JS-файла
  • удобен для локальной разработки
  • не требует дополнительных HTTP-запросов
  • ухудшает производительность загрузки в продакшене при больших бандлах
  • исключает проблему «потерянных» map-файлов

Применение

  • быстрый дебаг в dev-среде
  • тестовые сборки
  • среды без HTTP-сервера для map-файлов

external

Режим external создаёт отдельный .map файл и подключает его через ссылку в конце JavaScript-файла.

Поведение

  • генерируется bundle.js.map
  • в JS добавляется ссылка на файл
  • source map хранится отдельно

Пример

esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  outfile: 'dist/bundle.js',
  sourcemap: 'external'
});

Результат

Структура выходной директории:

dist/
 ├── bundle.js
 └── bundle.js.map

В bundle.js:

//# sourceMappingURL=bundle.js.map

Особенности

  • оптимален для продакшена при наличии отладочной информации
  • уменьшает размер JS-файла
  • позволяет кешировать .js и .map отдельно
  • требует корректной серверной настройки раздачи файлов

Применение

  • staging-среды
  • production с включённой отладкой
  • аналитика ошибок (Sentry, LogRocket и аналоги)

linked

Режим linked в esbuild по поведению близок к external, но делает акцент на явной связке source map с выходным файлом через стандартный механизм ссылок.

Поведение

  • создаётся внешний .map файл
  • в JS добавляется стандартная директива sourceMappingURL
  • связь строго файловая (без inline-кодирования)

Пример

esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  outfile: 'dist/app.js',
  sourcemap: 'linked'
});

Результат

dist/
 ├── app.js
 └── app.js.map

В конце app.js:

//# sourceMappingURL=app.js.map

Отличия от external

Формально linked и external в esbuild пересекаются по поведению, но концептуально:

  • linked подчёркивает связь через URL-указатель
  • external описывает сам факт вынесения map наружу

В реальных сборках esbuild эти режимы часто ведут к одинаковому результату, но различие важно при работе через разные интеграции или инструменты, которые могут интерпретировать режимы по-разному.

Особенности

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

both

Режим both включает сразу два способа представления source map:

  • inline-карта внутри файла
  • отдельный .map файл

Пример конфигурации

esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  outfile: 'dist/bundle.js',
  sourcemap: 'both'
});

Поведение сборки

Создаются два механизма отображения:

  1. Внутри bundle.js присутствует inline base64 source map
  2. В директории появляется bundle.js.map

Особенности

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

Использование в средах

  • сложные CI/CD пайплайны
  • системы анализа ошибок, требующие внешних map-файлов
  • локальная отладка при одновременной проверке файловой структуры

Сравнение режимов

inline

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

external

  • два файла
  • оптимальный баланс для production
  • требует корректной раздачи .map

linked

  • аналог external по структуре
  • подчёркнутая связь через URL
  • используется в строгих пайплайнах

both

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

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

Генерация source map в esbuild добавляет этап постобработки:

  • вычисление соответствий AST → output
  • запись дополнительных файлов
  • кодирование inline-карт

Режим inline обычно быстрее на этапе загрузки (меньше файлов), но тяжелее по размеру итогового бандла. Режимы external, linked и both увеличивают количество файлов, но облегчают сетевую доставку JS.


Взаимодействие с минификацией

При включённом minify source map сохраняет связь между:

  • оригинальными идентификаторами
  • минифицированными именами
  • позициями в коде

В режимах external, linked, both это особенно важно, поскольку позволяет инструментам восстановления стека точно сопоставлять ошибки с исходниками.


Особенности интеграции с watch-режимом

В режиме watch: true esbuild обновляет source map при каждом изменении исходных файлов.

  • inline — пересборка одного файла
  • external/linked — пересборка JS и map
  • both — полная пересборка двух представлений

Поведение в разных окружениях

браузер

  • inline снижает количество запросов
  • external/linked требуют корректного хостинга .map
  • both увеличивает точность дебага

Node.js

  • source map используется через инспектор
  • external предпочтителен для анализа stack trace

CI/CD

  • external/linked обеспечивают независимое хранение артефактов
  • inline используется редко из-за роста размера логов и файлов

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

Source map, сгенерированные esbuild, совместимы с:

  • Chrome DevTools
  • Firefox Debugger
  • Node.js inspector
  • Sentry и аналогами error tracking
  • bundler pipeline-инструментами (Vite, Rollup интеграции)

Итоговые особенности выбора режима

  • inline — минимальная инфраструктура, максимальная автономность
  • external — стандартная схема продакшена
  • linked — строгая файловая модель с явной связью
  • both — универсальный режим для сложных сценариев отладки и анализа