Сжатие литералов в процессе минификации основано на преобразовании константных значений в их наиболее компактное представление без изменения семантики программы. В ходе работы компилятора выполняется анализ выражений, определяются значения, которые могут быть вычислены на этапе сборки, и заменяются на готовые результаты.
Ключевая цель данного этапа — уменьшение объёма кода за счёт:
Одним из базовых механизмов является constant folding — вычисление выражений, результат которых известен заранее.
Примеры преобразований:
const a = 2 + 3;
преобразуется в:
const a = 5;
Аналогично для более сложных случаев:
const b = 10 * (2 + 3);
становится:
const b = 50;
Такая оптимизация применяется не только к числам, но и к строкам:
const msg = "Hello, " + "world";
результат:
const msg = "Hello, world";
При сжатии строк выполняется несколько уровней преобразований:
"a" + "b" + "c" к
"abc".Пример:
const path = "api/" + "v1/" + "users";
становится:
const path = "api/v1/users";
Дополнительно могут применяться преобразования Unicode-escape последовательностей в более компактный вид, если это не влияет на интерпретацию строки.
Логические операции являются одним из ключевых объектов оптимизации. При известном значении операндов выражения упрощаются до констант.
Примеры:
const a = true && false;
упрощается до:
const a = false;
const b = false || "value";
становится:
const b = "value";
Особое внимание уделяется трёхчастным выражениям:
const c = true ? 1 : 2;
результат:
const c = 1;
Тернарные выражения подвергаются глубокой оптимизации при наличии константных условий.
Пример:
const mode = "prod";
const isProd = mode === "prod" ? true : false;
преобразуется в:
const isProd = true;
Если ветви тернарного оператора содержат одинаковые значения, выражение полностью схлопывается:
const x = condition ? 10 : 10;
результат:
const x = 10;
При анализе условий с известным результатом происходит устранение недостижимых блоков.
if (false) {
doSomething();
}
полностью удаляется.
При более сложных условиях:
if (1 > 2) {
foo();
} else {
bar();
}
сохраняется только:
bar();
Такое поведение критически важно для уменьшения итогового размера бандла, особенно в условиях feature-flag логики.
Числовые операции оптимизируются с учётом приоритетов операторов и ассоциативности.
const x = 100 / 2 * 3;
преобразуется в:
const x = 150;
Также учитываются побочные свойства операций:
Примеры:
const a = n + 0;
→
const a = n;
const b = n * 1;
→
const b = n;
const c = n * 0;
→
const c = 0;
Если значение переменной известно на этапе сборки и не изменяется, оно может быть встроено непосредственно в места использования.
const SIZE = 1024;
const area = SIZE * 2;
становится:
const area = 1024 * 2;
а затем дополнительно:
const area = 2048;
Подобная цепочка оптимизаций формирует эффект каскадного упрощения.
В выражениях, где преобразование типов не влияет на результат, оно удаляется.
const a = !!true;
→
const a = true;
const b = Number("42");
→
const b = 42;
если строковый литерал является статическим и корректно парсится как число.
Многоуровневые выражения разбираются на составные части и приводятся к минимальной форме.
const x = (((2 + 3) * 4) - 0);
преобразуется последовательно:
const x = (5 * 4);
const x = 20;
При анализе выражений учитывается наличие побочных эффектов. Если выражение не влияет на состояние программы, оно может быть удалено.
"debug" && console.log("test");
остаётся без изменений, так как console.log имеет
побочный эффект.
Однако:
"debug" && 42;
упрощается до:
42;
или может быть удалено целиком, если результат не используется.
Побитовые операции также подвергаются свёртке:
const mask = 0xff & 0xff;
→
const mask = 255;
Аналогично:
const flag = 1 << 3;
→
const flag = 8;
Поведение сжатия литералов и выражений зависит от включённых режимов:
Комбинация этих режимов усиливает результат, однако именно оптимизация литералов и выражений даёт наиболее заметное уменьшение размера за счёт устранения избыточной вычислительной структуры.