## Архитектура трансформаций Next.js в SWC
Интеграция SWC в экосистему Next.js стала одним из наиболее значимых этапов развития инструментария современного JavaScript. Вместо использования Babel для большинства операций компиляции Next.js применяет высокопроизводительный компилятор SWC, написанный на языке Rust. Помимо стандартного преобразования современного JavaScript и TypeScript в код, совместимый с различными средами выполнения, SWC содержит набор специализированных трансформаций, разработанных непосредственно для нужд Next.js.
Эти трансформации обеспечивают:
* обработку JSX и React-компонентов;
* поддержку React Server Components;
* работу с маршрутизацией App Router;
* оптимизацию импортов;
* трансформацию переменных окружения;
* поддержку CSS-in-JS решений;
* внедрение служебного кода Next.js;
* автоматическую оптимизацию React-приложений;
* генерацию клиентских и серверных бандлов.
Особенность заключается в том, что многие из этих преобразований отсутствуют в стандартном SWC и реализованы исключительно внутри инфраструктуры Next.js.
---
## Трансформация JSX и React
Одной из базовых задач SWC в Next.js является преобразование JSX в обычный JavaScript.
Исходный код:
```jsx
export default function Page() {
return
Hello World
;
}
```
После компиляции:
```javascript
import { jsx as _jsx } from "react/jsx-runtime";
export default function Page() {
return _jsx("h1", {
children: "Hello World"
});
}
```
При использовании нового JSX Runtime автоматически подключаются функции из пакета:
```javascript
react/jsx-runtime
```
Разработчику не требуется импортировать React вручную:
```jsx
import React from "react";
```
Такая возможность обеспечивается специальной трансформацией SWC.
---
## Поддержка TypeScript
Next.js использует SWC для удаления типов TypeScript без выполнения проверки типов.
Исходный код:
```typescript
interface User {
name: string;
age: number;
}
const user: User = {
name: "Alex",
age: 25
};
```
После компиляции:
```javascript
const user = {
name: "Alex",
age: 25
};
```
Удаляются:
* интерфейсы;
* типы;
* дженерики;
* type aliases;
* объявления enum (в зависимости от конфигурации).
Проверка типов по-прежнему выполняется отдельным процессом через TypeScript Compiler (`tsc`).
---
## Трансформация React Fast Refresh
Во время разработки Next.js автоматически внедряет поддержку Fast Refresh.
Исходный компонент:
```jsx
export default function Button() {
return ;
}
```
После внутренних преобразований SWC добавляет служебные конструкции регистрации компонента:
```javascript
$RefreshReg$(Button, "Button");
```
Это позволяет:
* сохранять состояние компонентов;
* обновлять интерфейс без полной перезагрузки страницы;
* ускорять цикл разработки.
Трансформация работает только в режиме разработки.
---
## Поддержка React Server Components
Начиная с App Router Next.js активно использует React Server Components (RSC).
Файл:
```jsx
export default async function Page() {
const posts = await getPosts();
return (
{posts.length}
);
}
```
SWC анализирует модуль и определяет:
* является ли компонент серверным;
* требуется ли выполнение на клиенте;
* необходимо ли включать код в клиентский бандл.
На основании анализа формируются специальные серверные манифесты.
---
## Обработка директивы "use client"
Ключевая трансформация App Router связана с директивой:
```javascript
"use client";
```
Пример:
```jsx
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
);
}
```
SWC выполняет следующие действия:
1. Определяет модуль как клиентский.
2. Помещает его в клиентский бандл.
3. Создает ссылки между серверными и клиентскими компонентами.
4. Генерирует специальные идентификаторы модулей.
Без этой трансформации механизм разделения Server Components и Client Components был бы невозможен.
---
## Обработка директивы "use server"
Для серверных действий используется директива:
```javascript
"use server";
```
Пример:
```javascript
"use server";
export async function createPost(data) {
// логика сохранения
}
```
SWC обнаруживает такие функции и генерирует инфраструктурный код для:
* удаленного вызова;
* сериализации параметров;
* передачи данных между клиентом и сервером;
* регистрации Server Actions.
В результате вызов функции на клиенте автоматически преобразуется в серверный запрос.
---
## Трансформация переменных окружения
Next.js поддерживает внедрение переменных окружения непосредственно в код.
Исходный код:
```javascript
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
```
После компиляции:
```javascript
const apiUrl = "https://api.example.com";
```
Преимущества:
* отсутствие обращения к `process.env` во время выполнения;
* уменьшение накладных расходов;
* возможность дальнейшей оптимизации кода.
---
## Inline Environment Replacement
SWC выполняет частичное вычисление выражений.
Исходный код:
```javascript
if (process.env.NODE_ENV === "development") {
console.log("debug");
}
```
После подстановки:
```javascript
if ("production" === "development") {
console.log("debug");
}
```
Далее включается механизм Dead Code Elimination.
Результат:
```javascript
// код удален
```
Подобная оптимизация значительно уменьшает размер продакшен-сборок.
---
## Dead Code Elimination
SWC способен удалять заведомо недостижимый код.
Пример:
```javascript
if (false) {
heavyFunction();
}
```
После преобразования:
```javascript
// удалено
```
Другой пример:
```javascript
const DEBUG = false;
if (DEBUG) {
console.log("debug");
}
```
После анализа:
```javascript
// удалено
```
Особенно эффективно это работает совместно с подстановкой переменных окружения.
---
## Оптимизация импортов
Next.js содержит специальную трансформацию оптимизации импортов.
Исходный код:
```javascript
import { debounce } from "lodash";
```
Может быть преобразован в:
```javascript
import debounce from "lodash/debounce";
```
Преимущества:
* уменьшение размера бандла;
* ускорение загрузки;
* более эффективный tree shaking.
Функциональность используется через механизм:
```javascript
optimizePackageImports
```
---
## Modularize Imports
SWC поддерживает автоматическую модификацию импортов по шаблонам.
Пример конфигурации:
```javascript
modularizeImports: {
lodash: {
transform: "lodash/{{member}}"
}
}
```
Исходный код:
```javascript
import { map } from "lodash";
```
После трансформации:
```javascript
import map from "lodash/map";
```
Такой подход часто применяется для:
* lodash;
* date-fns;
* lodash-es;
* ramda;
* icon-библиотек.
---
## Поддержка styled-jsx
Встроенная система стилизации Next.js использует специальную трансформацию SWC.
Исходный код:
```jsx
{`
p {
color: red;
}
`}
```
Компилятор генерирует:
```html
```
и
```css
.jsx-123 {
color: red;
}
```
Каждый компонент получает уникальные идентификаторы стилей.
Это обеспечивает:
* изоляцию CSS;
* отсутствие конфликтов;
* автоматическое связывание компонентов со стилями.
---
## Поддержка Styled Components
SWC умеет выполнять специализированную трансформацию для Styled Components.
Исходный код:
```jsx
const Button = styled.button`
color: red;
`;
```
При включении:
```javascript
compiler: {
styledComponents: true
}
```
компилятор добавляет:
* displayName;
* SSR-поддержку;
* стабильные идентификаторы классов;
* оптимизации для гидратации.
---
## Поддержка Emotion
Для библиотеки Emotion также реализованы отдельные преобразования.
Конфигурация:
```javascript
compiler: {
emotion: true
}
```
SWC обеспечивает:
* корректный SSR;
* генерацию метаданных;
* поддержку source maps;
* оптимизацию стилей.
Это позволяет отказаться от Babel-плагинов Emotion.
---
## Трансформация Relay
Для проектов на Relay предусмотрена интеграция с SWC.
Пример конфигурации:
```javascript
compiler: {
relay: {
src: "./src"
}
}
```
Компилятор:
* анализирует GraphQL-запросы;
* связывает их с Relay Runtime;
* генерирует необходимые артефакты.
---
## Удаление свойств React
Для продакшен-сборок часто требуется убрать служебные атрибуты.
Исходный код:
```jsx
```
Удаляются атрибуты:
* `data-testid`;
* пользовательские служебные поля;
* тестовые маркеры.
---
## Удаление console-вызовов
SWC способен автоматически удалять вызовы консоли.
Конфигурация:
```javascript
compiler: {
removeConsole: true
}
```
Исходный код:
```javascript
console.log("debug");
console.warn("warning");
```
После компиляции:
```javascript
// удалено
```
Это уменьшает:
* размер бандла;
* количество побочных эффектов;
* риск утечки отладочной информации.
---
## Обработка динамических импортов
SWC анализирует конструкции:
```javascript
import("./dashboard");
```
и преобразует их в формат, необходимый для механизма code splitting Next.js.
Пример:
```javascript
const Dashboard = dynamic(
() => import("./dashboard")
);
```
Компилятор создает:
* отдельный чанк;
* таблицу зависимостей;
* информацию для предварительной загрузки.
---
## Поддержка next/font
Система шрифтов Next.js использует собственную трансформацию.
Исходный код:
```javascript
import { Inter } from "next/font/google";
const inter = Inter({
subsets: ["latin"]
});
```
SWC анализирует вызов и генерирует:
* загрузочные манифесты;
* CSS для шрифта;
* оптимизированные ресурсы.
В результате уменьшается количество сетевых запросов и исключается проблема FOIT/FOUT.
---
## Трансформация next/image
Компонент изображений также проходит через специальные этапы обработки.
Пример:
```jsx
```
SWC собирает метаданные, необходимые для:
* оптимизации изображений;
* генерации responsive-версий;
* построения preload-списков.
---
## Поддержка маршрутизации App Router
При использовании директории:
```text
app/
```
SWC анализирует файловую структуру и генерирует сведения о маршрутах.
Например:
```text
app/
├─ page.js
├─ blog/
│ └─ page.js
└─ dashboard/
└─ page.js
```
Формируются маршруты:
```text
/
/blog
/dashboard
```
Дополнительно создаются:
* серверные манифесты;
* клиентские манифесты;
* карты зависимостей компонентов.
---
## Генерация серверных и клиентских бандлов
Одной из наиболее сложных трансформаций Next.js является разделение приложения на несколько сред выполнения.
SWC определяет:
* серверный код;
* клиентский код;
* edge-код;
* общие модули.
После анализа формируются независимые наборы файлов для каждой среды.
Такой механизм лежит в основе:
* React Server Components;
* Server Actions;
* App Router;
* Edge Runtime.
---
## Трансформация Edge Runtime
Для файлов, выполняемых в Edge Runtime, SWC дополнительно проверяет совместимость API.
Пример:
```javascript
export const runtime = "edge";
```
Компилятор учитывает ограничения среды выполнения:
* отсутствие Node.js API;
* использование Web API;
* работу в изолированном окружении.
На основе анализа формируется отдельный edge-бандл.
---
## Анализ экспортов страниц
SWC обрабатывает специальные экспорты Next.js.
Пример:
```javascript
export const revalidate = 60;
```
или:
```javascript
export const dynamic = "force-static";
```
или:
```javascript
export const runtime = "edge";
```
Компилятор извлекает подобные настройки во время сборки и передает их системе маршрутизации и рендеринга.
Благодаря этому многие решения принимаются ещё до запуска приложения, что позволяет Next.js строить более эффективные серверные и клиентские бандлы, выполнять статическую генерацию страниц, использовать инкрементальную регенерацию и оптимизировать работу React Server Components без дополнительных затрат во время выполнения.