Поле jsc.loose
## Поле `jsc.loose`
Поле `jsc.loose` в конфигурации SWC определяет режим генерации JavaScript-кода с упрощённой семантикой преобразований. Оно влияет на то, насколько строго транспиляция следует спецификации ECMAScript при преобразовании современных конструкций языка в более старый JavaScript.
Включение этого режима изменяет стратегию генерации кода: вместо максимально корректного с точки зрения спецификации поведения SWC использует более «свободные» и производительные паттерны, которые часто дают меньший и более быстрый результат, но могут отличаться от эталонной семантики языка в редких крайних случаях.
---
## Общая идея loose-режима
Loose-режим в SWC — это компромисс между:
* строгим соответствием спецификации ECMAScript;
* размером итогового кода;
* скоростью выполнения;
* сложностью генерируемых вспомогательных конструкций.
Когда `jsc.loose` включён, трансформации становятся менее «симулирующими» поведение движка JavaScript и более «практическими», ориентированными на типичные сценарии использования.
---
## Тип конфигурации
Поле задаётся в секции `jsc`:
```json
{
"jsc": {
"loose": true
}
}
```
Допустимые значения:
* `true` — включение упрощённой генерации кода;
* `false` — строгая трансформация с полным соблюдением спецификации (значение по умолчанию).
---
## Влияние на трансформации
### Классы
Одно из наиболее заметных изменений происходит при трансформации классов.
#### Строгий режим (`loose: false`)
SWC стремится воспроизвести поведение ECMAScript-классов максимально точно:
* корректная работа дескрипторов свойств;
* точная эмуляция `[[DefineOwnProperty]]`;
* аккуратная обработка наследования;
* сохранение всех спецификационных гарантий.
#### Loose-режим (`loose: true`)
Генерация упрощается:
* свойства записываются напрямую на прототип;
* используется обычное присваивание вместо `Object.defineProperty`;
* часть проверок пропускается;
* уменьшается количество вспомогательных вызовов.
Пример:
```js
class A {
method() {}
}
```
Строгая трансформация:
```js
Object.defineProperty(A.prototype, "method", {
value: function () {},
enumerable: false,
configurable: true,
writable: true
});
```
Loose-трансформация:
```js
A.prototype.method = function () {};
```
Разница заключается в семантической точности и объёме генерируемого кода.
---
### Наследование классов
При `loose: true` упрощается цепочка наследования.
Строгий режим учитывает все спецификационные шаги:
* создание промежуточного конструктора;
* корректное связывание `prototype`;
* обработку `super`.
Loose-режим минимизирует количество вспомогательных операций:
```js
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
```
В некоторых случаях оптимизации идут дальше, сокращая дополнительные проверки.
---
### Свойства объектов
При работе с объектными литералами и свойствами различия проявляются в деталях определения дескрипторов.
#### Строгий режим
Каждое свойство может быть определено с точными флагами:
* enumerable;
* configurable;
* writable.
#### Loose-режим
Свойства записываются напрямую:
```js
obj.key = value;
```
Это ускоряет выполнение, но убирает возможность точного контроля дескрипторов в процессе трансформации.
---
### Производительность генерации
Включение `jsc.loose` обычно приводит к следующим эффектам:
* уменьшение размера итогового кода;
* снижение количества вызовов `Object.*` методов;
* ускорение выполнения в рантайме;
* сокращение времени трансформации.
Эти эффекты особенно заметны в больших кодовых базах с интенсивным использованием классов и объектов.
---
## Семантические отличия
Loose-режим не является полностью эквивалентным спецификации ECMAScript. Основные отличия:
### Потеря точной имитации дескрипторов
Вместо полного соответствия `PropertyDescriptor` используется прямое присваивание.
### Упрощённое поведение наследования
Некоторые edge-case сценарии с `super` и динамическими изменениями прототипа могут вести себя иначе.
### Меньшее количество защитных проверок
Например:
* отсутствие дополнительных проверок на конфигурируемость;
* пропуск части валидаций при установке свойств.
---
## Влияние на совместимость
`jsc.loose: true` наиболее безопасен в следующих случаях:
* код ориентирован на современные движки;
* отсутствует необходимость точного соответствия спецификации;
* приоритет — скорость выполнения;
* проект использует стандартные паттерны ООП без метапрограммирования через дескрипторы.
Менее безопасен:
* при активном использовании `Object.defineProperty`;
* при сложной работе с прототипами во время выполнения;
* при библиотечной разработке, где важна предсказуемость на уровне спецификации.
---
## Связь с другими опциями SWC
`jsc.loose` часто используется совместно с другими трансформационными флагами:
* `jsc.transform.class` — определяет, какие именно преобразования классов включены;
* `jsc.target` — задаёт целевую версию ECMAScript;
* `jsc.externalHelpers` — влияет на вынесение вспомогательных функций;
* `module.type` — определяет тип модулей.
Loose-режим усиливает эффект оптимизаций, заданных в этих полях.
---
## Поведение в крупных трансформациях
При обработке больших проектов влияние `jsc.loose` становится системным:
* уменьшается количество вспомогательных функций, генерируемых SWC;
* упрощается AST-обработка классов;
* ускоряется pipeline компиляции;
* сокращается глубина трансформационных проходов.
В монорепозиториях это может приводить к заметному снижению времени сборки.
---
## Ограничения и потенциальные риски
Использование loose-режима вводит ряд ограничений:
* невозможность полагаться на точное соответствие ECMAScript;
* потенциальные расхождения в редких edge-case сценариях;
* зависимость поведения от оптимизаций транспилятора, а не спецификации языка;
* сложность отладки при взаимодействии с низкоуровневыми механизмами объектов.
---
## Поведение по умолчанию
Если `jsc.loose` не указан, SWC использует строгий режим (`false`), при котором:
* сохраняется максимальная совместимость со спецификацией;
* увеличивается объём генерируемого кода;
* трансформации становятся более предсказуемыми;
* возрастает количество runtime-операций.
---