SWC строится вокруг модульного компиляционного конвейера, где каждый
этап преобразования AST может быть расширен через плагины на Rust или
WebAssembly. Плагин в SWC — это функция трансформации дерева
синтаксического анализа, работающая на уровне swc_ecma_ast,
с доступом к контексту компиляции через swc_common.
Типовой жизненный цикл плагина включает:
Отладка в такой архитектуре требует понимания того, на каком именно этапе происходит искажение данных: парсинг, трансформация или кодогенерация.
Основная сложность плагинов SWC заключается в том, что входные и выходные данные представлены не строками, а структурированными узлами AST. Ошибки редко проявляются напрямую — чаще они выражаются в некорректной структуре дерева или нарушении инвариантов.
Ключевые источники проблем:
span;
Expr, Stmt,
ModuleItem.
Отладка начинается с изоляции трансформации: плагин должен быть минимизирован до одной операции над узлом.
Rust-плагины SWC не имеют классического console.log,
поэтому применяется стандартная инфраструктура логирования Rust:
eprintln! для быстрого вывода в stderr;
println! при запуске через CLI;
tracing для структурированного логирования.
Пример диагностического вывода:
eprintln!("Visiting node: {:?}", &expr);
Однако прямой вывод AST быстро становится нечитабельным. Более эффективный подход — логирование отдельных характеристик:
Expr::Call, Stmt::If);
node.span.lo, node.span.hi);
Debug или кастомный
форматтер.
Одна из ключевых причин некорректного поведения плагинов — нарушение
Span. SWC использует Span для связи AST с
исходным кодом.
При трансформациях важно:
Span при клонировании;
DUMMY_SP только для синтетических узлов;
Типичная ошибка:
Expr::Ident(Ident {
span: DUMMY_SP,
sym: "value".into(),
..
})
Такой код ломает source map и делает отладку почти невозможной.
Корректный подход — наследование span от ближайшего контекстного узла.
SWC активно использует паттерн Visitor для обхода AST. Отладка строится вокруг переопределения методов:
visit_expr
visit_stmt
visit_module_item
Диагностическая версия visitor часто включает:
Пример:
fn visit_expr(&mut self, n: Expr) -> Expr {
eprintln!("IN: {:?}", n);
let transformed = n;
eprintln!("OUT: {:?}", transformed);
transformed
}
Такой подход позволяет локализовать точку искажения данных.
Модуль swc_common предоставляет систему ошибок,
интегрированную в компиляционный контекст.
Основные инструменты:
Handler для накопления ошибок;
SpanLabel для указания точных позиций;
emit_diagnostic для расширенной информации.
Пример генерации ошибки:
handler
.struct_span_err(span, "Invalid transformation")
.note("Expected identifier but found expression")
.emit();
Это особенно важно при разработке сложных трансформаций, где ошибка должна быть привязана к исходному коду.
При сложных плагинах эффективна стратегия многоступенчатого дампа AST:
Для сериализации используется swc_ecma_codegen или
serde-подобные инструменты.
Пример упрощённого дампа:
eprintln!("{}", debug_ast(&module));
или через кодогенерацию:
let mut buf = Vec::new();
let mut gen = Emitter::new(&mut buf, None, false, false);
gen.emit_module(&module)?;
Rust-основа SWC делает владение критическим фактором отладки. Частые ошибки:
Типичный симптом — panic в глубине visit_* методов.
Корректная стратегия:
.clone() для узлов перед модификацией;
Box<T> и
Vec<T>.
WASM-плагины добавляют дополнительный слой сложности: ограниченную наблюдаемость и отсутствие стандартного stderr в привычном виде.
Основные подходы:
console_error_panic_hook;
Пример:
web_sys::console::log_1(&format!("{:?}", node).into());
Также важно учитывать, что оптимизация WASM может убирать часть логики, если она не используется явно.
Ключевой метод диагностики — воспроизведение ошибки на минимальном коде.
Стратегия:
Snapshot-тесты позволяют сравнивать AST до и после трансформации:
assert_eq!(format!("{:?}", output), snapshot);
Ошибки в source map часто маскируют реальные проблемы трансформации. Проверка включает:
lo/hi;
При подозрении на повреждение source map полезно отключить его генерацию и сравнить поведение кода.
На практике повторяются следующие классы проблем:
visit_children;
Диагностика этих проблем сводится к контролю обхода дерева и строгому соблюдению порядка трансформаций.
Эффективная модель отладки SWC-плагинов строится вокруг трёх уровней:
Совмещение этих уровней позволяет локализовать ошибку до конкретного узла и конкретной операции трансформации.