Поле module.type и его параметры
## module.type: назначение и роль в системе модульной трансформации SWC
Поле `module.type` в конфигурации SWC определяет стратегию преобразования модулей JavaScript/TypeScript при компиляции. Оно управляет тем, в какой модульный формат будет трансформирован исходный код: останется ли он в формате ES Modules или будет преобразован в CommonJS, AMD, UMD либо другие поддерживаемые системы модулей.
На уровне компилятора SWC модульная система — один из ключевых этапов трансформации, влияющий на совместимость кода с окружением выполнения (Node.js, браузер, bundler-инструменты).
---
## Расположение в конфигурации SWC
Параметр задаётся внутри секции `module` файла конфигурации `.swcrc`:
```json
{
"module": {
"type": "es6"
}
}
```
Структура секции обычно включает:
* `type` — тип выходной модульной системы
* дополнительные параметры (в зависимости от выбранного типа и версии SWC)
---
## Основные значения module.type
### es6 (ES Modules)
Значение `es6` сохраняет или генерирует код в формате ES Modules (`import` / `export`).
#### Поведение:
* `import` остаётся без преобразования
* `export` сохраняется
* подходит для современных bundler’ов (Vite, Rollup, esbuild)
* используется в браузерных приложениях с поддержкой ESM
#### Пример трансформации:
Исходный код:
```js
export const sum = (a, b) => a + b;
```
Результат:
```js
export const sum = (a, b) => a + b;
```
---
### commonjs
Наиболее часто используемый вариант для Node.js-окружения.
#### Поведение:
* `import` преобразуется в `require`
* `export` преобразуется в `module.exports` или `exports.*`
* добавляется runtime-обвязка для совместимости
#### Пример:
Исходный код:
```js
export function sum(a, b) {
return a + b;
}
```
Результат:
```js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.sum = sum;
function sum(a, b) {
return a + b;
}
```
---
### amd
Asynchronous Module Definition — формат, используемый в RequireJS и подобных системах.
#### Поведение:
* оборачивает модуль в `define([...], function(...) {})`
* зависимости явно перечисляются
* используется редко в современных проектах
#### Пример:
```js
define(["exports"], function (exports) {
"use strict";
exports.sum = sum;
function sum(a, b) {
return a + b;
}
});
```
---
### umd
Universal Module Definition — универсальный формат, поддерживающий сразу несколько окружений:
* AMD
* CommonJS
* глобальный контекст браузера
#### Поведение:
* генерируется IIFE-обёртка
* определяется окружение выполнения
* выбирается подходящий механизм экспорта
#### Пример структуры:
```js
(function (global, factory) {
if (typeof module === "object" && typeof module.exports === "object") {
module.exports = factory();
} else if (typeof define === "function" && define.amd) {
define([], factory);
} else {
global.MyLib = factory();
}
})(this, function () {
return {};
});
```
---
### systemjs
Формат для SystemJS loader.
#### Поведение:
* используется `System.register`
* зависимости и экспорты описываются декларативно
* применяется в специфичных сборках legacy-проектов
---
## Поведение трансформации import/export
Выбор `module.type` напрямую влияет на то, как SWC обрабатывает синтаксис модулей:
### import
* `es6` → без изменений
* `commonjs` → `require()`
* `amd` → аргументы `define([...])`
* `umd` → комбинированная стратегия
### export
* именованные экспорты → `exports.name = ...` (commonjs)
* default export → `module.exports = ...`
* ESM → остаётся неизменным
---
## Взаимодействие с другими параметрами module
### module.noInterop
Контролирует поведение interop между CommonJS и ES Modules.
При `type: "commonjs"` часто используется совместно:
```json
{
"module": {
"type": "commonjs",
"noInterop": false
}
}
```
#### Влияние:
* управляет генерацией `__esModule`
* влияет на доступ к default export
---
### module.strict
Определяет режим генерации строгой модульной обёртки.
#### Влияние:
* добавляет `"use strict"`
* предотвращает небезопасные конструкции
* улучшает совместимость с современными стандартами JS
---
### module.lazy
Используется для оптимизации загрузки модулей.
#### Поведение:
* откладывает инициализацию модулей
* может уменьшать стартовую стоимость выполнения
* особенно полезно в bundler-цепочках
---
## Влияние module.type на tree-shaking
Хотя SWC сам по себе не выполняет полноценный tree-shaking, выбор `module.type` влияет на возможности последующих инструментов:
### es6
* сохраняет статическую структуру модулей
* оптимально для tree-shaking в bundler’ах
### commonjs
* динамическая система `require`
* усложняет статический анализ
* снижает эффективность удаления неиспользуемого кода
---
## Совместимость с Node.js
### ESM-режим Node.js
При использовании:
```json
{ "type": "module" }
```
Оптимально:
```json
{ "module": { "type": "es6" } }
```
### CommonJS-режим Node.js
Без ESM-флагов:
```json
{ "module": { "type": "commonjs" } }
```
---
## Частые комбинации конфигураций
### Библиотека для npm (универсальная)
```json
{
"module": {
"type": "commonjs"
}
}
```
или двойная сборка:
* ESM сборка (`es6`)
* CJS сборка (`commonjs`)
---
### Фронтенд-приложение
```json
{
"module": {
"type": "es6"
}
}
```
---
### Legacy-браузеры и RequireJS
```json
{
"module": {
"type": "amd"
}
}
```
---
## Влияние на генерацию кода и runtime-обвязки
Выбор `module.type` определяет необходимость дополнительных конструкций:
* helper-функции для interop (`__esModule`)
* обёртки модулей (IIFE, define, System.register)
* преобразование синтаксиса динамических импортов
* поведение top-level scope
---
## Особенности обработки default export
### ES6
```js
export default function () {}
```
### CommonJS
```js
module.exports = function () {};
```
При этом SWC может добавлять вспомогательные поля:
```js
exports.default = ...
```
в зависимости от режима interop.
---
## Ограничения и нюансы
* `module.type` не управляет bundling — только трансформацией
* динамические `require()` не всегда корректно анализируются
* tree-shaking зависит от внешнего инструмента
* поведение может отличаться между версиями SWC при обновлениях пресетов
* некоторые комбинации с TypeScript `isolatedModules` требуют дополнительной настройки
---
## Поведение при отсутствии module.type
Если `module.type` не указан:
* SWC может сохранять исходный формат (в зависимости от входных файлов)
* либо применять дефолтный режим окружения
* поведение может отличаться между конфигурациями CLI и интеграциями (Next.js, bundlers)
---