Skip to content

Il flag --define ti permette di dichiarare costanti e globali staticamente analizzabili. Sostituisce tutti gli usi di un identificatore o proprietà in un file JavaScript o TypeScript con un valore costante. Questa funzionalità è supportata a runtime e anche in bun build. È simile a #define in C/C++, ma per JavaScript.

sh
bun --define process.env.NODE_ENV="'production'" src/index.ts # Runtime
bun build --define process.env.NODE_ENV="'production'" src/index.ts # Build

Questi valori staticamente noti sono usati da Bun per l'eliminazione del codice morto e altre ottimizzazioni.

ts
if (process.env.NODE_ENV === "production") {
  console.log("Modalità produzione");
} else {
  console.log("Modalità sviluppo");
}

Prima che il codice raggiunga il motore JavaScript, Bun sostituisce process.env.NODE_ENV con "production".

ts
if ("production" === "production") { 
  console.log("Modalità produzione");
} else {
  console.log("Modalità sviluppo");
}

Non si ferma qui. Il transpilatore ottimizzante di Bun è abbastanza intelligente da fare un po' di folding costante di base.

Poiché "production" === "production" è sempre true, Bun sostituisce l'intera espressione con il valore true.

ts
if (true) { 
  console.log("Modalità produzione");
} else {
  console.log("Modalità sviluppo");
}

E infine, Bun rileva che il ramo else non è raggiungibile e lo elimina.

ts
console.log("Modalità produzione");

Quali tipi di valori sono supportati?

I valori possono essere stringhe, identificatori, proprietà o JSON.

Sostituire identificatori globali

Per rendere tutti gli usi di window come undefined, puoi usare il seguente comando.

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

Questo può essere utile quando si fa Server-Side Rendering (SSR) o quando vuoi assicurarti che il codice non dipenda dall'oggetto window.

js
if (typeof window !== "undefined") {
  console.log("Codice lato client");
} else {
  console.log("Codice lato server");
}

Puoi anche impostare il valore come un altro identificatore. Ad esempio, per rendere tutti gli usi di global come globalThis, puoi usare il seguente comando.

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

global è un oggetto globale in Node.js, ma non nei browser web. Quindi, puoi usarlo per correggere alcuni casi in cui il codice presuppone che global sia disponibile.

Sostituire valori con JSON

--define può anche essere usato per sostituire valori con oggetti e array JSON.

Per sostituire tutti gli usi di AWS con l'oggetto JSON {"ACCESS_KEY":"abc","SECRET_KEY":"def"}, puoi usare il seguente comando.

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

Questi verranno trasformati nel codice JavaScript equivalente.

Da:

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

A:

ts
console.log("abc");

Sostituire valori con altre proprietà

Puoi anche passare proprietà al flag --define.

Ad esempio, per sostituire tutti gli usi di console.write con console.log, puoi usare il seguente comando

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

Questo trasforma il seguente input:

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

Nel seguente output:

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

In che modo questo è diverso dall'impostazione di una variabile?

Puoi anche impostare process.env.NODE_ENV su "production" nel tuo codice, ma questo non aiuterà con l'eliminazione del codice morto. In JavaScript, gli accessi alle proprietà possono avere effetti collaterali. I getter e setter possono essere funzioni e anche definiti dinamicamente (a causa delle catene di prototipi e Proxy). Anche se imposti process.env.NODE_ENV su "production", nella riga successiva, non è sicuro per gli strumenti di analisi statica assumere che process.env.NODE_ENV sia "production".

In che modo questo è diverso dal trova-e-sostituisci o dalla sostituzione di stringhe?

Il flag --define opera a livello di AST (Abstract Syntax Tree), non a livello di testo. Avviene durante il processo di transpilazione, il che significa che può essere usato in ottimizzazioni come l'eliminazione del codice morto.

Gli strumenti di sostituzione di stringhe tendono ad avere problemi di escaping e sostituiscono parti non intenzionali del codice.

Bun a cura di www.bunjs.com.cn