## Роль SWC в экосистеме Vitest
**Vitest** представляет собой современный фреймворк тестирования для JavaScript и TypeScript, тесно интегрированный с экосистемой Vite. Одним из ключевых факторов производительности Vitest является скорость обработки исходного кода перед выполнением тестов. Для этой задачи может использоваться **SWC (Speedy Web Compiler)** — высокопроизводительный компилятор, написанный на языке Rust.
SWC выполняет несколько важных функций:
* трансформация современного JavaScript в более совместимый код;
* компиляция TypeScript;
* преобразование JSX и TSX;
* обработка декораторов;
* минификация;
* генерация source maps.
В контексте Vitest SWC чаще всего применяется как замена Babel или встроенному трансформеру TypeScript для ускорения подготовки тестируемого кода.
---
## Почему SWC используется вместе с Vitest
При запуске тестов происходит несколько этапов:
1. Загрузка файлов.
2. Анализ зависимостей.
3. Трансформация исходного кода.
4. Выполнение тестов.
5. Формирование отчётов.
На крупных проектах именно этап трансформации способен занимать значительную часть времени.
Традиционные решения:
| Инструмент | Язык реализации |
| ------------------------- | --------------- |
| Babel | JavaScript |
| TypeScript Compiler (tsc) | TypeScript |
| SWC | Rust |
За счёт нативной реализации SWC зачастую обеспечивает ускорение в несколько раз по сравнению с Babel.
Особенно заметна разница при:
* тысячах тестовых файлов;
* крупных монорепозиториях;
* интенсивном использовании TypeScript;
* проектах с React и JSX.
---
## Архитектура взаимодействия Vitest и SWC
Упрощённая схема выглядит следующим образом:
```text
Исходный файл
│
▼
SWC
│
▼
Трансформированный код
│
▼
Vitest
│
▼
Выполнение тестов
```
SWC отвечает исключительно за компиляцию и преобразование кода.
Vitest занимается:
* запуском тестов;
* мокированием модулей;
* отслеживанием изменений;
* изоляцией окружения;
* сбором результатов.
Такое разделение обязанностей позволяет использовать максимально быстрый трансформер без изменения логики тестирования.
---
## Установка SWC
Для большинства проектов требуется установить основные пакеты:
```bash
npm install -D @swc/core
```
или
```bash
yarn add -D @swc/core
```
или
```bash
pnpm add -D @swc/core
```
Если используется React:
```bash
npm install -D @swc/core @swc/helpers
```
Пакет `@swc/helpers` содержит вспомогательные функции, которые могут генерироваться во время трансформации кода.
---
## Конфигурация SWC через файл .swcrc
SWC поддерживает отдельный конфигурационный файл.
Пример:
```json
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"target": "es2022"
},
"module": {
"type": "es6"
}
}
```
Разберём параметры подробнее.
### parser.syntax
Определяет тип входного кода.
Для Jav * aScript:
```json
{
"syntax": "ecmascript"
}
```
Для TypeScript:
```json
{
"syntax": "typescript"
}
```
---
### parser.tsx
Активирует поддержку TSX.
```json
{
"tsx": true
}
```
Необходим для React-приложений на TypeScript.
---
### parser.decorators
Поддержка декораторов.
```json
{
"decorators": true
}
```
Актуально для NestJS и других проектов, использующих экспериментальные возможности языка.
---
### jsc.target
Указывает целевую версию JavaScript.
Например:
```json
{
"target": "es2015"
}
```
или
```json
{
"target": "es2022"
}
```
Чем современнее целевая платформа, тем меньше преобразований выполняет SWC.
---
## Использование SWC с TypeScript
Одним из наиболее популярных сценариев является тестирование TypeScript-кода.
Исходный файл:
```ts
export function sum(a: number, b: number): number {
return a + b;
}
```
После трансформации SWC удаляет типы:
```js
export function sum(a, b) {
return a + b;
}
```
Важно понимать принцип работы.
SWC:
* удаляет типы;
* компилирует синтаксис.
SWC не выполняет:
* проверку типов;
* анализ корректности типизации.
Поэтому проверка типов обычно выносится в отдельную команду:
```bash
tsc --noEmit
```
Часто используются оба процесса:
```bash
npm run test
npm run typecheck
```
Такой подход обеспечивает одновременно высокую скорость и строгий контроль типов.
---
## React, JSX и TSX
SWC обладает встроенной поддержкой React.
Пример компонента:
```tsx
export function Button() {
return ;
}
```
Конфигурация:
```json
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"transform": {
"react": {
"runtime": "automatic"
}
}
}
}
```
Параметр:
```json
{
"runtime": "automatic"
}
```
включает современную JSX-трансформацию React без необходимости импортировать React вручную.
---
## Поддержка Decorators
Во многих корпоративных проектах используются декораторы.
Пример:
```ts
class UserService {
@Log()
create() {}
}
```
Настройка:
```json
{
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
}
}
}
```
Параметры:
| Опция | Назначение |
| ----------------- | ---------------------------- |
| legacyDecorator | Поддержка legacy-декораторов |
| decoratorMetadata | Генерация metadata |
Такая конфигурация часто используется совместно с NestJS.
---
## Настройка через vite.config.ts
Поскольку Vitest построен поверх Vite, большинство настроек задаётся через конфигурацию Vite.
Пример:
```ts
import { defineConfig } from "vite";
export default defineConfig({
test: {
globals: true,
environment: "node"
}
});
```
Если в проекте используется плагин SWC, он также подключается здесь.
---
## Использование SWC в React-проектах на Vite
Наиболее распространённый вариант:
```bash
npm install -D @vitejs/plugin-react-swc
```
Конфигурация:
```ts
import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [react()]
});
```
Теперь:
* React-компоненты компилируются через SWC;
* Vitest использует ту же инфраструктуру преобразования;
* сокращается время запуска тестов.
---
## Сравнение Babel и SWC в Vitest
### Babel
Преимущества:
* огромная экосистема;
* множество плагинов;
* зрелость решения.
Недостатки:
* более медленная компиляция;
* значительное потребление памяти.
---
### SWC
Преимущества:
* высокая скорость;
* низкое потребление ресурсов;
* поддержка TypeScript и JSX из коробки.
Недостатки:
* меньше плагинов;
* часть возможностей Babel может отсутствовать.
---
## Source Maps в тестах
Source maps позволяют видеть реальные строки исходного файла при возникновении ошибок.
Настройка:
```json
{
"sourceMaps": true
}
```
Без source maps стек вызовов может выглядеть так:
```text
dist/file.js:421
```
Со включёнными картами:
```text
src/services/user.ts:18
```
Это значительно упрощает отладку.
---
## Трансформация модулей
SWC способен преобразовывать различные форматы модулей.
ESM:
```json
{
"module": {
"type": "es6"
}
}
```
CommonJS:
```json
{
"module": {
"type": "commonjs"
}
}
```
Для современных проектов на Vitest предпочтительным вариантом считается ESM.
---
## Использование алиасов
Во многих проектах применяются абсолютные пути.
Пример:
```ts
import { UserService } from "@/services/UserService";
```
Настройка производится через Vite:
```ts
import path from "path";
export default {
resolve: {
alias: {
"@": path.resolve(__dirname, "./src")
}
}
};
```
После этого SWC корректно обрабатывает импорты при запуске тестов.
---
## Производительность при запуске тестов
При использовании SWC ускорение становится заметным в нескольких сценариях.
### Большое количество TypeScript-файлов
Каждый файл требует удаления типов и преобразования синтаксиса.
SWC выполняет это значительно быстрее стандартного компилятора TypeScript.
---
### React-проекты
Компиляция JSX является одной из наиболее затратных операций.
SWC оптимизирован специально для подобных задач.
---
### Монорепозитории
В репозиториях с десятками пакетов количество файлов может достигать десятков тысяч.
SWC позволяет заметно сократить:
* холодный запуск;
* повторные прогоны;
* время работы CI.
---
## Ограничения SWC
Несмотря на высокую производительность, существуют особенности, которые необходимо учитывать.
### Отсутствие проверки типов
SWC не заменяет TypeScript Compiler.
Ошибочный код:
```ts
const age: number = "30";
```
может быть успешно скомпилирован.
Контроль типов должен выполняться отдельно.
---
### Ограниченная экосистема плагинов
Babel существует значительно дольше.
Поэтому некоторые редкие плагины могут не иметь аналогов в SWC.
---
### Различия в трансформациях
В отдельных случаях результат работы Babel и SWC может отличаться.
Особенно это касается:
* экспериментальных возможностей языка;
* нестандартных Babel-плагинов;
* сложных цепочек трансформаций.
Перед миграцией крупных проектов рекомендуется проверять совместимость тестового окружения.
---
## Практическая конфигурация для Vitest и React
Файл `vite.config.ts`:
```ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: "jsdom",
setupFiles: "./src/setupTests.ts"
}
});
```
Файл `.swcrc`:
```json
{
"jsc": {
"target": "es2022",
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true
},
"transform": {
"react": {
"runtime": "automatic"
}
}
},
"sourceMaps": true
}
```
Такая конфигурация обеспечивает:
* быструю компиляцию TypeScript;
* поддержку React и TSX;
* корректную обработку декораторов;
* удобную отладку через source maps;
* высокую скорость запуска тестов в Vitest.
---
## Рекомендации по использованию SWC в тестовой инфраструктуре
Для большинства современных проектов оптимальной считается следующая схема:
```text
TypeScript
│
▼
SWC
│
▼
Vitest
│
▼
Выполнение тестов
```
При этом проверка типов запускается отдельно:
```bash
tsc --noEmit
```
Подобная архитектура позволяет объединить преимущества двух инструментов:
* максимальную скорость компиляции благодаря SWC;
* полноценную типовую безопасность благодаря TypeScript Compiler;
* быстрый запуск тестов через Vitest;
* эффективную работу в крупных кодовых базах и CI/CD-конвейерах.