Skip to content

A flag --define permite declarar constantes e globais estaticamente analisáveis. Ela substitui todos os usos de um identificador ou propriedade em um arquivo JavaScript ou TypeScript por um valor constante. Este recurso é suportado em tempo de execução e também em bun build. Isso é meio que similar a #define em C/C++, exceto que para JavaScript.

sh
bun --define process.env.NODE_ENV="'production'" src/index.ts # Tempo de execução
bun build --define process.env.NODE_ENV="'production'" src/index.ts # Build

Esses valores estaticamente conhecidos são usados pelo Bun para eliminação de código morto e outras otimizações.

ts
if (process.env.NODE_ENV === "production") {
  console.log("Modo produção");
} else {
  console.log("Modo desenvolvimento");
}

Antes do código chegar ao motor JavaScript, o Bun substitui process.env.NODE_ENV por "production".

ts
if ("production" === "production") { 
  console.log("Modo produção");
} else {
  console.log("Modo desenvolvimento");
}

Não para por aí. O transpilador otimizador do Bun é inteligente o suficiente para fazer alguma dobra de constante básica.

Como "production" === "production" é sempre true, o Bun substitui toda a expressão pelo valor true.

ts
if (true) { 
  console.log("Modo produção");
} else {
  console.log("Modo desenvolvimento");
}

E finalmente, o Bun detecta que o branch else não é alcançável e o elimina.

ts
console.log("Modo produção");

Quais tipos de valores são suportados?

Valores podem ser strings, identificadores, propriedades ou JSON.

Substituir identificadores globais

Para fazer todos os usos de window serem undefined, você pode usar o seguinte comando.

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

Isso pode ser útil quando faz Server-Side Rendering (SSR) ou quando quer ter certeza de que o código não depende do objeto window.

js
if (typeof window !== "undefined") {
  console.log("Código client-side");
} else {
  console.log("Código server-side");
}

Você também pode definir o valor como outro identificador. Por exemplo, para fazer todos os usos de global serem globalThis, você pode usar o seguinte comando.

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

global é um objeto global no Node.js, mas não em navegadores web. Então, você pode usar isso para corrigir alguns casos onde o código assume que global está disponível.

Substituir valores com JSON

--define também pode ser usado para substituir valores por objetos e arrays JSON.

Para substituir todos os usos de AWS pelo objeto JSON {"ACCESS_KEY":"abc","SECRET_KEY":"def"}, você pode usar o seguinte comando.

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

Esses serão transformados no código JavaScript equivalente.

De:

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

Para:

ts
console.log("abc");

Substituir valores com outras propriedades

Você também pode passar propriedades para a flag --define.

Por exemplo, para substituir todos os usos de console.write por console.log, você pode usar o seguinte comando

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

Isso transforma a seguinte entrada:

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

Na seguinte saída:

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

Como isso é diferente de definir uma variável?

Você também pode definir process.env.NODE_ENV como "production" em seu código, mas isso não ajudá com eliminação de código morto. Em JavaScript, acessos a propriedades podem ter efeitos colaterais. Getters e setters podem ser funções e até mesmo definidos dinamicamente (devido a cadeias de protótipo e Proxy). Mesmo se você definir process.env.NODE_ENV como "production", na próxima linha, não é seguro para ferramentas de análise estática assumirem que process.env.NODE_ENV é "production".

Como isso é diferente de find-and-replace ou substituição de string?

A flag --define opera no nível AST (Abstract Syntax Tree), não no nível de texto. Ela acontece durante o processo de transpilação, o que significa que pode ser usada em otimizações como eliminação de código morto.

Ferramentas de substituição de string tendem a ter problemas de escaping e substituem partes não intencionais do código.

Bun by www.bunjs.com.cn edit