Карты источников (source maps) связывают сгенерированный JavaScript-код с исходным кодом, написанным на TypeScript, современном JavaScript или JSX. При трансформации кода через SWC исходная структура программы часто изменяется: исчезают типы, разворачиваются синтаксические конструкции, инлайнятся вспомогательные функции. Без карт источников отладка превращается в работу с результатом компиляции, а не с исходным кодом.
Source map представляет собой JSON-структуру, которая описывает соответствие между:
Ключевая задача SWC в этом контексте — сохранить точную трассировку изменений при трансформациях и минимизации.
Внутри SWC генерация карт источников встроена в фазу codegen. После того как AST (абстрактное синтаксическое дерево) проходит трансформации (парсинг, транспиляция, оптимизация), генератор кода формирует:
Каждое преобразование узла AST может:
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 без изменения
отладочного пайплайна.