Поле sourceMaps: генерация карт источников

Назначение source maps в процессе трансляции

Карты источников (source maps) связывают сгенерированный JavaScript-код с исходным кодом, написанным на TypeScript, современном JavaScript или JSX. При трансформации кода через SWC исходная структура программы часто изменяется: исчезают типы, разворачиваются синтаксические конструкции, инлайнятся вспомогательные функции. Без карт источников отладка превращается в работу с результатом компиляции, а не с исходным кодом.

Source map представляет собой JSON-структуру, которая описывает соответствие между:

  • позициями в итоговом файле (generated code)
  • позициями в исходных файлах (original source)
  • именами переменных и символов

Ключевая задача SWC в этом контексте — сохранить точную трассировку изменений при трансформациях и минимизации.


Модель генерации source maps в SWC

Внутри SWC генерация карт источников встроена в фазу codegen. После того как AST (абстрактное синтаксическое дерево) проходит трансформации (парсинг, транспиляция, оптимизация), генератор кода формирует:

  • итоговый JavaScript
  • структуру mapping’ов (соответствий)

Каждое преобразование узла AST может:

  • изменить позицию токенов
  • добавить новые узлы (например, helpers)
  • удалить исходные конструкции (например, TypeScript аннотации)

SWC компенсирует эти изменения, формируя таблицу соответствий.


Конфигурация sourceMaps в SWC

Основной способ управления генерацией карт источников — поле sourceMaps в конфигурации .swcrc.

Базовый пример

{
  "jsc": {
    "parser": {
      "syntax": "typescript"
    },
    "target": "es2020"
  },
  "sourceMaps": true
}

При значении true SWC создаёт отдельный .map файл рядом с выходным JavaScript.


Режимы работы sourceMaps

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

false

Source maps не генерируются. Это максимальная производительность сборки, но отсутствие отладочной информации.

{
  "sourceMaps": false
}

Используется в production-сборках, где важен размер и скорость выполнения, а не отладка.


true

Создаётся внешний .map файл.

{
  "sourceMaps": true
}

Результат:

  • bundle.js
  • bundle.js.map

В конец JS-файла добавляется ссылка:

//

Inline source maps

SWC может встраивать карту прямо в файл:

{
  "sourceMaps": "inline"
}

В этом случае:

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

Пример:

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

Этот режим удобен для тестирования и локальной разработки, но увеличивает размер файла.


Combined mode (inline + external)

В некоторых сборочных сценариях используется комбинированный подход:

{
  "sourceMaps": "both"
}

Поведение:

  • создаётся .map файл
  • одновременно вставляется inline-ссылка

Применяется редко, чаще в сложных пайплайнах, где инструменты ожидают разные форматы source maps.


Связь source maps с трансформацией AST

Генерация карт в SWC происходит на уровне каждого узла AST. При обработке узла фиксируются:

  • стартовая позиция исходного узла
  • конечная позиция
  • соответствующий диапазон в output-коде

Каждая трансформация может менять геометрию кода:

Пример: удаление TypeScript типов

Исходный код:

function sum(a: number, b: number): number {
  return a + b;
}

После SWC:

function sum(a, b) {
  return a + b;
}

Source map связывает:

  • a: number → удалённый сегмент
  • : number (return type) → удалён
  • тело функции сохраняет точные позиции

Влияние minification на source maps

При включённой минификации (minify: true) структура кода существенно меняется:

{
  "jsc": {
    "minify": {
      "compress": true,
      "mangle": true
    }
  },
  "sourceMaps": true
}

Минификация влияет на:

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

SWC обязан сохранять корректную связь между:

  • оригинальными идентификаторами
  • их изменёнными версиями

Пример маппинга переменных

До:

function calculateTotal(price, tax) {
  return price + tax;
}

После:

function a(b,c){return b+c}

Source map содержит таблицу:

  • calculateTotal → a
  • price → b
  • tax → c

Поле inlineSourcesContent

Дополнительный параметр, влияющий на полноту карты:

{
  "sourceMaps": true,
  "inlineSourcesContent": true
}

При включении SWC добавляет исходный код прямо в source map:

"sourcesContent": [
  "function sum(a, b) { return a + b; }"
]

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


Структура генерируемого source map

Типичная карта источников включает следующие поля:

  • version — версия спецификации (обычно 3)
  • file — имя выходного файла
  • sources — список исходных файлов
  • sourcesContent — содержимое исходников (опционально)
  • names — список идентификаторов
  • mappings — VLQ-кодированная строка соответствий
  • sourceRoot — базовый путь для исходников

SWC формирует эти данные автоматически на основе AST и контекста сборки.


Интеграция SWC source maps с инструментами сборки

Webpack (swc-loader)

При использовании SWC как loader:

module.exports = {
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: "swc-loader",
          options: {
            sourceMaps: true
          }
        }
      }
    ]
  }
}

Webpack дополнительно агрегирует карты, создавая единый source map для всего бандла.


Next.js (SWC runtime)

В экосистеме Next.js SWC используется как основной транспилятор. Source maps включаются автоматически в development-режиме и могут быть отключены в production.

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

  • генерация карт происходит на уровне страницы
  • поддерживается трассировка server + client кода
  • карты разделяются по чанкам

Node.js + @swc/core

При программном использовании:

import { transformFile } from "@swc/core";

const result = await transformFile("input.ts", {
  sourceMaps: true,
  jsc: {
    parser: {
      syntax: "typescript"
    }
  }
});

Результат содержит:

  • code
  • map

Особенности генерации при JSX и TypeScript

JSX

При трансформации JSX в React.createElement или automatic runtime:

const el = <div>Hello</div>;

SWC создаёт mapping между:

  • JSX-узлом
  • вызовом runtime-функции

Даже при изменении структуры DOM-выражения сохраняется привязка к строкам JSX.


TypeScript

TypeScript-специфичные конструкции полностью исчезают:

  • типы интерфейсов
  • generics
  • enum (при определённых настройках)

Source maps сохраняют только runtime-значимые элементы.


Производительность генерации source maps

Генерация карт источников в SWC оптимизирована:

  • используется потоковая генерация mapping’ов
  • минимизируются промежуточные структуры
  • применяется компактное VLQ-кодирование

Однако включение source maps увеличивает:

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

В больших проектах разница становится заметной при:

  • минификации
  • bundling’е
  • многомодульной компиляции

Типичные проблемы и особенности поведения

Несовпадение строк при агрессивной оптимизации

При включённой оптимизации SWC может:

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

Это усложняет точное восстановление оригинального контекста, но SWC компенсирует это через сегментные mappings.


Потеря source maps при постобработке

Если после SWC применяется дополнительный инструмент (например, terser или кастомный bundler), карты могут:

  • перезаписываться
  • игнорироваться
  • требовать ремаппинга

Inline source maps и размер файла

При использовании inline режима:

  • размер JS может увеличиться в 2–5 раз
  • ухудшается кеширование CDN
  • замедляется загрузка в браузере

Поведение в dev и production окружении

Типичный паттерн конфигурации:

  • development: sourceMaps: true или “inline”
  • production: sourceMaps: false или отдельная генерация

Причина разделения:

  • в dev важна отладка
  • в prod важна скорость и размер

Роль source maps в отладке через DevTools

Браузерные DevTools используют source maps для:

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

SWC-генерируемые карты позволяют восстановить:

  • оригинальные строки TypeScript
  • JSX-структуру компонентов
  • имена функций до минификации

Совместимость формата SWC source maps

SWC следует стандарту Source Map Revision 3, что обеспечивает совместимость с:

  • Chrome DevTools
  • Firefox Debugger
  • Node.js inspector
  • bundlers (Webpack, Vite, Rollup)

Это позволяет использовать SWC как замену Babel без изменения отладочного пайплайна.