Skip to content

Флаг --define позволяет объявлять статически анализируемые константы и глобальные переменные. Он заменяет все использования идентификатора или свойства в JavaScript или TypeScript файле на константное значение. Эта функция поддерживается во время выполнения, а также в bun build. Это похоже на #define в C/C++, но для JavaScript.

sh
bun --define process.env.NODE_ENV="'production'" src/index.ts # Время выполнения
bun build --define process.env.NODE_ENV="'production'" src/index.ts # Сборка

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

ts
if (process.env.NODE_ENV === "production") {
  console.log("Режим продакшена");
} else {
  console.log("Режим разработки");
}

Прежде чем код достигнет JavaScript-движка, Bun заменяет process.env.NODE_ENV на "production".

ts
if ("production" === "production") { 
  console.log("Режим продакшена");
} else {
  console.log("Режим разработки");
}

На этом всё не заканчивается. Оптимизирующий транспилятор Bun достаточно умен, чтобы выполнять некоторую базовую свёртку констант.

Поскольку "production" === "production" всегда true, Bun заменяет всё выражение на значение true.

ts
if (true) { 
  console.log("Режим продакшена");
} else {
  console.log("Режим разработки");
}

И наконец, Bun обнаруживает, что ветка else недостижима, и удаляет её.

ts
console.log("Режим продакшена");

Какие типы значений поддерживаются?

Значения могут быть строками, идентификаторами, свойствами или JSON.

Замена глобальных идентификаторов

Чтобы сделать все использования window равными undefined, вы можете использовать следующую команду.

sh
bun --define window="undefined" src/index.ts

Это может быть полезно при серверном рендеринге (SSR) или когда вы хотите убедиться, что код не зависит от объекта window.

js
if (typeof window !== "undefined") {
  console.log("Клиентский код");
} else {
  console.log("Серверный код");
}

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

sh
bun --define global="globalThis" src/index.ts

global — это глобальный объект в Node.js, но не в веб-браузерах. Таким образом, вы можете использовать это для исправления некоторых случаев, когда код предполагает, что global доступен.

Замена значений на JSON

--define также можно использовать для замены значений на JSON-объекты и массивы.

Чтобы заменить все использования AWS на JSON-объект {"ACCESS_KEY":"abc","SECRET_KEY":"def"}, вы можете использовать следующую команду.

sh
# JSON
bun --define AWS='{"ACCESS_KEY":"abc","SECRET_KEY":"def"}' src/index.ts

Они будут преобразованы в эквивалентный JavaScript-код.

Из:

ts
console.log(AWS.ACCESS_KEY); // => "abc"

В:

ts
console.log("abc");

Замена значений другими свойствами

Вы также можете передавать свойства флагу --define.

Например, чтобы заменить все использования console.write на console.log, вы можете использовать следующую команду.

sh
bun --define console.write=console.log src/index.ts

Это преобразует следующий входной код:

ts
console.write("Hello, world!");

В следующий выходной код:

ts
console.log("Hello, world!");

Чем это отличается от установки переменной?

Вы также можете установить process.env.NODE_ENV в "production" в вашем коде, но это не поможет с удалением мёртвого кода. В JavaScript доступ к свойствам может иметь побочные эффекты. Геттеры и сеттеры могут быть функциями и даже динамически определены (из-за цепочек прототипов и Proxy). Даже если вы установите process.env.NODE_ENV в "production", в следующей строке не будет безопасно для инструментов статического анализа предполагать, что process.env.NODE_ENV равен "production".

Чем это отличается от поиска и замены или замены строк?

Флаг --define работает на уровне AST (абстрактного синтаксического дерева), а не на текстовом уровне. Это происходит во время транспиляции, что означает, что его можно использовать в оптимизациях, таких как удаление мёртвого кода.

Инструменты замены строк часто имеют проблемы с экранированием и заменяют непреднамеренные части кода.

Bun от www.bunjs.com.cn