Кэширование в SWC
## Кэширование в SWC
### Общие принципы кэширования в SWC
Кэширование в SWC строится вокруг ускорения повторных преобразований исходного кода за счёт сохранения результатов трансформации и промежуточных представлений. Основная цель — минимизация повторной работы компилятора при инкрементальной сборке, изменении небольшого числа файлов и частых пересборках в dev-режиме.
В отличие от традиционных JavaScript-трансформеров, SWC реализован на Rust, что позволяет эффективно сочетать низкоуровневую оптимизацию с кэшированием на уровне файловой системы и памяти. Кэширование здесь не является второстепенной оптимизацией — оно встроено в архитектуру трансформационного пайплайна.
---
### Архитектура кэширования
Кэш в SWC можно условно разделить на несколько уровней:
* файловый кэш трансформаций
* кэш конфигурации компилятора
* кэш зависимостей модулей
* интеграционный кэш (Webpack, Next.js, Turborepo)
Каждый уровень отвечает за отдельный аспект повторного использования результатов.
---
### Файловый кэш трансформаций
Основной механизм ускорения работы связан с сохранением результата преобразования AST → JavaScript.
При трансформации файла учитываются:
* содержимое исходного файла
* конфигурация `.swcrc`
* версия SWC и используемых плагинов
* параметры трансформации (target, minify, module type)
На основе этих данных формируется **cache key**, который используется для обращения к файловому кэшу.
Типичный поток работы:
1. Чтение исходного файла
2. Вычисление хеша содержимого
3. Комбинирование хеша с конфигурацией
4. Проверка наличия результата в кэше
5. Возврат результата или выполнение трансформации
6. Запись результата в кэш
Кэш может храниться в виде сериализованных AST или уже сгенерированного JavaScript-кода.
---
### Кэширование в @swc/core
В Node.js-окружении через `@swc/core` кэширование чаще всего контролируется опосредованно — через обёртки сборщиков и фреймворков. Однако базовая логика остаётся общей: повторное преобразование идентичных входных данных избегается.
Особенность заключается в том, что SWC не всегда хранит кэш глобально — часто он делегируется внешним инструментам (Webpack, Next.js, Turborepo).
---
### Интеграция с Webpack и swc-loader
В связке с `swc-loader` для Webpack кэширование реализуется на двух уровнях:
* кэш Webpack (memory / filesystem cache)
* кэш трансформаций SWC
Webpack хранит результат загрузчиков, а SWC внутри загрузчика может дополнительно проверять актуальность входных данных.
Типичная конфигурация включает:
* включение `cacheDirectory`
* использование persistent cache Webpack
* контроль версий конфигурации `.swcrc`
Принцип взаимодействия:
* Webpack определяет, изменился ли модуль
* `swc-loader` проверяет, изменился ли результат трансформации
* при совпадении используется закэшированный результат
---
### Кэширование в Next.js
В экосистеме Next.js SWC используется как основной транспайлер. Здесь кэширование встроено глубоко в сборочный процесс:
* `.next/cache/swc` хранит результаты трансформаций
* инкрементальная сборка опирается на hash графа модулей
* пересборка выполняется только для изменённых узлов графа
Особенность заключается в том, что кэш учитывает не только файл, но и контекст:
* env-переменные
* target окружения (server/client)
* режим сборки (development/production)
---
### Turborepo и распределённый кэш
В монорепозиториях SWC часто используется вместе с Turborepo, где кэширование выходит за пределы одной машины.
Принцип работы:
* вычисление hash задачи (inputs + dependencies)
* сохранение результата трансформации
* возможность повторного использования кэша из удалённого хранилища
SWC в этом случае выступает как генератор детерминированных артефактов, которые могут быть безопасно разделены между CI и локальной средой.
---
### Инвалидация кэша
Критически важная часть системы — корректное определение устаревших записей.
Основные триггеры инвалидирования:
* изменение исходного файла
* изменение `.swcrc`
* обновление версии SWC
* изменение зависимостей (import graph)
* изменение окружения сборки
Для предотвращения некорректных результатов используется **версионирование cache key**, включающее:
* hash содержимого
* hash конфигурации
* semantic version SWC
---
### Структура cache key
Типичный cache key в SWC формируется как комбинация:
* SHA256 содержимого файла
* сериализованной конфигурации трансформации
* флагов minify / module / target
* версии трансформера
Результатом становится стабильный идентификатор, гарантирующий, что одинаковые входные данные всегда используют одинаковый кэш.
---
### Memory cache vs filesystem cache
В SWC используются два основных типа хранения:
**Memory cache**
* быстрый доступ
* используется в dev-сценариях
* ограниченный жизненный цикл процесса
**Filesystem cache**
* устойчив к перезапуску процесса
* применяется в production сборках
* требует контроля размера и очистки
Часто используется гибридная модель: memory cache как LRU-слой поверх файлового.
---
### Кэширование и трансформации JSX/TypeScript
Особенно эффективно кэширование проявляется при работе с:
* JSX трансформациями
* TypeScript stripping
* decorators
* minification
Так как AST-представление часто повторяется между сборками, SWC может переиспользовать не только результат, но и частично промежуточные узлы дерева.
---
### Плагины и влияние на кэш
При использовании SWC plugins кэширование усложняется:
* плагины могут быть недетерминированными
* изменяют AST произвольно
* требуют включения версии плагина в cache key
Любое изменение логики плагина автоматически инвалидирует соответствующие записи кэша.
---
### Проблемы и ограничения кэширования
На практике возникают следующие ограничения:
* несогласованность кэша в монорепозиториях при ручных изменениях
* некорректная инвалидация при динамических конфигурациях
* рост размера файлового кэша при длительных CI-сборках
* влияние сторонних плагинов на детерминизм результатов
Особенно критичны случаи, когда конфигурация SWC формируется динамически в runtime — это затрудняет стабильное вычисление cache key.
---
### Оптимизация поведения кэша
Эффективное использование кэша в SWC обычно достигается через:
* фиксированную конфигурацию `.swcrc`
* минимизацию динамических параметров трансформации
* контроль версий зависимостей
* разделение build/dev режимов
* использование стабильных путей кэша в CI
При правильной настройке кэширование превращается в основной механизм ускорения сборки, сокращая время трансформации до долей секунды для уже обработанных модулей.
---