Skip to content

El flag --define te permite declarar constantes y globales estáticamente analizables. Reemplaza todos los usos de un identificador o propiedad en un archivo de JavaScript o TypeScript con un valor constante. Esta característica es compatible en tiempo de ejecución y también en bun build. Esto es similar a #define en C/C++, pero para JavaScript.

sh
bun --define process.env.NODE_ENV="'production'" src/index.ts # Tiempo de ejecución
bun build --define process.env.NODE_ENV="'production'" src/index.ts # Compilación

Estos valores estáticamente conocidos son usados por Bun para la eliminación de código muerto y otras optimizaciones.

ts
if (process.env.NODE_ENV === "production") {
  console.log("Modo producción");
} else {
  console.log("Modo desarrollo");
}

Antes de que el código llegue al motor de JavaScript, Bun reemplaza process.env.NODE_ENV con "production".

ts
if ("production" === "production") { 
  console.log("Modo producción");
} else {
  console.log("Modo desarrollo");
}

No se detiene ahí. El transpilador optimizador de Bun es lo suficientemente inteligente como para hacer algún plegado de constantes básico.

Dado que "production" === "production" siempre es true, Bun reemplaza toda la expresión con el valor true.

ts
if (true) { 
  console.log("Modo producción");
} else {
  console.log("Modo desarrollo");
}

Y finalmente, Bun detecta que la rama else no es alcanzable y la elimina.

ts
console.log("Modo producción");

¿Qué tipos de valores son compatibles?

Los valores pueden ser cadenas, identificadores, propiedades o JSON.

Reemplazar identificadores globales

Para hacer que todos los usos de window sean undefined, puedes usar el siguiente comando.

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

Esto puede ser útil cuando se renderiza del lado del servidor (SSR) o cuando quieres asegurarte de que el código no dependa del objeto window.

js
if (typeof window !== "undefined") {
  console.log("Código del lado del cliente");
} else {
  console.log("Código del lado del servidor");
}

También puedes establecer el valor como otro identificador. Por ejemplo, para hacer que todos los usos de global sean globalThis, puedes usar el siguiente comando.

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

global es un objeto global en Node.js, pero no en navegadores web. Así que puedes usar esto para corregir algunos casos donde el código asume que global está disponible.

Reemplazar valores con JSON

--define también se puede usar para reemplazar valores con objetos y arrays JSON.

Para reemplazar todos los usos de AWS con el objeto JSON {"ACCESS_KEY":"abc","SECRET_KEY":"def"}, puedes usar el siguiente comando.

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

Esos se transformarán en el código JavaScript equivalente.

De:

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

A:

ts
console.log("abc");

Reemplazar valores con otras propiedades

También puedes pasar propiedades al flag --define.

Por ejemplo, para reemplazar todos los usos de console.write con console.log, puedes usar el siguiente comando

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

Eso transforma la siguiente entrada:

ts
console.write("¡Hola, mundo!");

En la siguiente salida:

ts
console.log("¡Hola, mundo!");

¿En qué se diferencia esto de establecer una variable?

También puedes establecer process.env.NODE_ENV en "production" en tu código, pero eso no ayudará con la eliminación de código muerto. En JavaScript, los accesos a propiedades pueden tener efectos secundarios. Los getters y setters pueden ser funciones e incluso definidos dinámicamente (debido a cadenas de prototipos y Proxy). Incluso si estableces process.env.NODE_ENV en "production", en la siguiente línea, no es seguro para las herramientas de análisis estático asumir que process.env.NODE_ENV es "production".

¿En qué se diferencia esto de buscar y reemplazar o reemplazo de cadenas?

El flag --define opera a nivel de AST (Árbol de Sintaxis Abstracta), no a nivel de texto. Ocurre durante el proceso de transpilación, lo que significa que se puede usar en optimizaciones como la eliminación de código muerto.

Las herramientas de reemplazo de cadenas tienden a tener problemas con el escape y reemplazan partes no intencionadas del código.

Bun por www.bunjs.com.cn editar