Минификация идентификаторов

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

Ключевой этап перед переименованием заключается в обходе AST и построении дерева областей видимости. Каждый блок, функция и модуль формирует собственный scope, внутри которого регистрируются объявления:

  • переменные var, let, const
  • параметры функций
  • объявления функций и классов
  • импортированные символы

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

Особое значение имеет разделение на глобальные и локальные области. Глобальные символы либо не изменяются, либо переименовываются с учётом конфигурации, чтобы не нарушить взаимодействие с внешними окружениями (например, браузерными API или Node.js глобалами).

Алгоритм генерации коротких имён

После завершения анализа SWC переходит к генерации новых идентификаторов. Используется последовательное кодирование, аналогичное base52/base64-подобным схемам, где имена формируются из набора допустимых символов Jav * aScript:

  • латинские буквы a–z, A–Z
  • при необходимости цифры 0–9

Генератор гарантирует уникальность имён внутри одного scope, увеличивая длину идентификатора только при исчерпании пространства коротких комбинаций.

Пример преобразования:

  • calculateTotalPricea
  • itemsb
  • indexc

При этом вложенные области могут использовать те же короткие имена, поскольку их пространства изолированы.

Сохранение семантики при переименовании

Основная сложность минификации идентификаторов заключается в корректной обработке ссылок. Каждое использование переменной должно быть связано с её декларацией через symbol resolution. SWC опирается на предварительно построенные ссылки между узлами AST.

При переименовании учитываются следующие ограничения:

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

Пример:

const { token, user } = response;
console.log(token, user);

После минификации:

const { a, b } = response;
console.log(a, b);

Здесь сохраняется связь между паттерном деструктуризации и ссылками на значения.

Обработка функций и параметров

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

function fetchData(url, options) {
  const result = request(url, options);
  return result;
}

Преобразуется в:

function a(b, c) {
  const d = request(b, c);
  return d;
}

Особое внимание уделяется функциям высшего порядка и вложенным функциям, где возможны перекрытия имён. В таких случаях генератор имён использует разные пространства символов для каждого уровня вложенности.

Работа с классами

В классах SWC отдельно обрабатывает:

  • имена классов
  • методы
  • приватные поля (при наличии трансформаций)
  • статические свойства

Имена методов рассматриваются как свойства прототипа и могут быть минифицированы только при условии, что доступ к ним не осуществляется через строковые литералы.

class UserService {
  getUser(id) {
    return db.find(id);
  }
}

Преобразуется в:

class a {
  b(c) {
    return db.find(c);
  }
}

При этом имя класса может быть сохранено или изменено в зависимости от настроек, например при включённой опции сохранения имён классов для отладки.

Влияние модульной системы

В ECMAScript модулях SWC учитывает связи между import и export. Экспортируемые символы могут быть переименованы локально, но их внешнее имя должно сохраняться либо транслироваться в соответствии с экспортной таблицей.

export function parseConfig(input) {
  return JSON.parse(input);
}

После обработки:

export function a(b) {
  return JSON.parse(b);
}

При этом импортирующие модули получают корректную привязку через реэкспортную карту, что исключает разрыв связей.

Конфликты и стратегии разрешения

При генерации коротких идентификаторов возможны коллизии между разными типами символов. SWC решает эту проблему через:

  • разделение namespace по scope
  • учёт hoisting для var и function declarations
  • изоляцию import binding
  • проверку зарезервированных слов JavaScript

Зарезервированные идентификаторы (eval, arguments, super, ключевые слова языка) исключаются из пула генерации.

Дополнительно учитываются глобальные объекты окружения. Например, в браузере нельзя без специальной настройки переименовывать window или document, если они используются напрямую.

Опции управления минификацией идентификаторов

Конфигурация SWC позволяет тонко управлять поведением алгоритма:

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

Эти параметры влияют на этап генерации символов и фильтрацию узлов AST перед переименованием.

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

Минификация идентификаторов тесно связана с другими оптимизациями:

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

После удаления ненужных узлов уменьшается количество символов, подлежащих переименованию, что повышает эффективность генерации коротких имён и снижает вероятность длинных идентификаторов в итоговом коде.

При этом порядок проходов имеет значение: сначала выполняется анализ и упрощение AST, затем — переименование символов, после чего возможны дополнительные проходы для финальной очистки.