strict и strictMode

Строгий режим JavaScript (strict mode) — это ограниченный вариант исполнения языка, в котором устраняются некоторые исторические неоднозначности и опасные конструкции. В SWC он влияет прежде всего на этап парсинга и частично на трансформации кода, поскольку компилятор обязан учитывать синтаксические и семантические ограничения строгого режима при обработке исходного текста.

SWC работает как транспайлер и парсер ECMAScript/TypeScript, и при включённом строгом режиме поведение синтаксического анализатора становится более жёстким: часть конструкций перестаёт быть допустимой на этапе разбора, а некоторые идентификаторы и формы записи интерпретируются иначе.


Поведение строгого режима в ECMAScript

Строгий режим вводит набор правил, влияющих на выполнение и синтаксис:

  • запрещается использование необъявленных переменных
  • исключается конструкция with
  • ограничивается использование зарезервированных слов
  • изменяется поведение this в функциях
  • запрещаются дублирующиеся параметры функций
  • запрещаются восьмеричные литералы в старом формате (0123)
  • eval и arguments получают изолированное поведение

Эти правила формируют более предсказуемую модель исполнения, которая критически важна для современных инструментов трансляции, включая SWC.


strictMode в SWC

В SWC строгий режим управляется на уровне парсера. Основная настройка задаётся в конфигурации .swcrc, в секции jsc.parser.

Типичная конфигурация:

{
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "strictMode": true
    }
  }
}

Параметр strictMode: true заставляет SWC интерпретировать весь входной код как находящийся в строгом режиме, независимо от наличия директивы “use strict” в исходном файле.

Если значение false, строгий режим применяется только тогда, когда он явно включён в коде через директиву.


Различие между strictMode и “use strict”

Семантически существует два уровня активации строгого режима:

Директива в коде

"use strict";

function test() {
  x = 10; // ReferenceError в strict mode
}

Принудительный режим в SWC

{
  "jsc": {
    "parser": {
      "strictMode": true
    }
  }
}

Во втором случае даже при отсутствии строки “use strict” код разбирается и анализируется так, как если бы строгий режим был активирован глобально.


Влияние на синтаксический анализ

SWC использует строгий режим на этапе парсинга AST. Это означает, что ошибки выявляются раньше трансформаций.

Запрещённые конструкции

Неявные глобальные переменные

function demo() {
  value = 10;
}

В строгом режиме SWC трактует это как ошибку привязки идентификатора.

Дублирующиеся параметры

function sum(a, a) {
  return a + a;
}

В строгом режиме такая сигнатура функции становится синтаксически недопустимой.

Octal literals

const n = 0123;

В строгом режиме запрещается старый восьмеричный формат, допускается только 0o123.


Влияние на AST и трансформации

SWC строит AST (Abstract Syntax Tree), который затем используется для трансформации и генерации кода. В строгом режиме структура AST может отличаться за счёт:

  • более жёсткой валидации узлов
  • отсутствия некоторых нестрогих форм выражений
  • различий в интерпретации идентификаторов

Это особенно важно для плагинов SWC и кастомных трансформеров, которые опираются на корректность дерева.


strictMode и модули ES

ES Modules (import / export) по спецификации всегда находятся в строгом режиме. В SWC это означает, что при использовании модуля:

import { x } from "./mod.js";

function test() {
  y = 10;
}

даже при strictMode: false парсер фактически применяет строгие правила.

Это поведение соответствует ECMAScript-спецификации: модульный код не может быть нестрогим.


strictMode в TypeScript-парсере SWC

При использовании TypeScript:

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "strictMode": true
    }
  }
}

строгий режим влияет только на JavaScript-часть синтаксиса. TypeScript-аннотации (: string, interface, type) обрабатываются отдельно, но JavaScript-правила строгого режима продолжают применяться.

Пример:

function fn(a, a: number) {
  return a;
}

Такая конструкция будет отклонена как нарушение строгого режима независимо от TypeScript-типов.


Влияние на трансформацию кода

SWC не только парсит код, но и трансформирует его в совместимый JavaScript. При строгом режиме трансформации могут:

  • исключать небезопасные конструкции
  • нормализовать поведение функций
  • предотвращать генерацию кода, нарушающего strict semantics

Пример влияния на генерацию:

Исходный код:

function f(a, b) {
  return arguments[0] + arguments[1];
}

В строгом режиме поведение arguments не связывается с именованными параметрами напрямую, и трансформер обязан сохранять корректную семантику доступа к arguments.


strictMode и Babel-подобные трансформации

SWC часто используется как альтернатива Babel, и строгий режим влияет на совместимость трансформаций:

  • плагины JSX должны учитывать строгий контекст
  • преобразования классов не могут опираться на нестрогие особенности this
  • оптимизации должны сохранять строгую семантику вызовов

Особенно критично это для классов:

class A {
  method() {
    console.log(this);
  }
}

В строгом режиме this внутри метода не преобразуется в глобальный объект, что влияет на поведение при отрыве метода от экземпляра.


Ошибки компиляции при strictMode

SWC в строгом режиме генерирует ошибки на этапе парсинга, а не трансформации.

Типичные сообщения:

  • unexpected reserved word
  • duplicate parameter name not allowed in this context
  • octal literals are not allowed in strict mode
  • assignment to undeclared variable

Это уменьшает вероятность появления некорректного AST, который мог бы привести к ошибкам во время выполнения.


Совместимость strictMode с современным JavaScript

Современные версии ECMAScript делают строгий режим стандартом для большинства конструкций:

  • модули всегда strict
  • классы всегда strict
  • многие новые синтаксические конструкции предполагают строгую семантику

SWC учитывает это при парсинге, поэтому strictMode становится не столько опцией выбора, сколько механизмом выравнивания поведения старого и нового кода.


Роль strictMode в пайплайне SWC

В типичном пайплайне обработки:

  1. Парсинг исходного кода
  2. Построение AST
  3. Применение трансформаций
  4. Генерация JavaScript

strictMode влияет в первую очередь на первый и частично на второй этап. Ошибки выявляются на этапе разбора, что предотвращает попадание некорректных узлов в последующие стадии.


Взаимодействие strictMode и конфигурации SWC

Кроме parser.strictMode, в SWC существуют другие настройки, которые косвенно взаимодействуют с ним:

  • jsc.target — влияет на генерацию кода, но не на строгость парсинга
  • jsc.loose — может ослаблять некоторые трансформационные правила, но не отменяет strict semantics
  • module.type — определяет модульный режим, который всегда strict
  • minify — может менять структуру кода, но обязан сохранять строгую семантику

Комбинация этих параметров определяет итоговое поведение компилятора.


Поведение в смешанных кодовых базах

В проектах, где часть файлов написана в старом стиле, а часть использует ES Modules, strictMode в SWC позволяет унифицировать обработку:

  • старые скрипты анализируются как strict при включённой опции
  • модули всегда strict независимо от настройки
  • различия между legacy и modern кодом уменьшаются на уровне компиляции

Это снижает вероятность появления runtime-ошибок, связанных с неоднозначной семантикой JavaScript.