> ## Documentation Index
> Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 定义并替换静态全局变量和常量

`--define` 标志允许你声明静态可分析的常量和全局变量。它会将 JavaScript 或 TypeScript 文件中所有对某个标识符或属性的使用替换为一个常量值。此功能在运行时和 `bun build` 中均受到支持。这有点类似于 C/C++ 中的 `#define`，只是针对 JavaScript 实现的。

```sh terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun --define process.env.NODE_ENV="'production'" src/index.ts # 运行时
bun build --define process.env.NODE_ENV="'production'" src/index.ts # 构建时
```

***

Bun 使用这些静态已知的值进行死代码消除和其他优化。

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
if (process.env.NODE_ENV === "production") {
  console.log("生产模式");
} else {
  console.log("开发模式");
}
```

***

在代码到达 JavaScript 引擎之前，Bun 会将 `process.env.NODE_ENV` 替换为 `"production"`。

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
if ("production" === "production") { // [!code ++]
  console.log("生产模式");
} else {
  console.log("开发模式");
}
```

***

这还不是终点。Bun 的优化转译器足够智能，可以进行一些基本的常量折叠。

由于 `"production" === "production"` 始终为 `true`，Bun 会将整个表达式替换为 `true` 值，并移除不可达的 `else` 分支。

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
if (true) { // [!code ++]
  console.log("生产模式");
}
```

***

要同时折叠周围的 `if` 脚手架并生成下面的最小输出，请传递 `--minify-syntax`（`--minify` 也会启用此选项）：

```sh terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun build --define process.env.NODE_ENV="'production'" --minify-syntax src/index.ts
```

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
console.log("生产模式");
```

***

## 支持哪些类型的值？

值可以是字符串、标识符、属性或 JSON。

### 替换全局标识符

如果想让所有对 `window` 的使用均为 `undefined`，可以使用以下命令。

```sh theme={"theme":{"light":"github-light","dark":"dracula"}}
bun --define window="undefined" src/index.ts
```

这在服务器端渲染（SSR）时非常有用，或者当你想确保代码不依赖 `window` 对象时。

```js theme={"theme":{"light":"github-light","dark":"dracula"}}
if (typeof window !== "undefined") {
  console.log("客户端代码");
} else {
  console.log("服务器端代码");
}
```

你也可以将值设置为另一个标识符。例如，要将所有对 `global` 的使用替换成 `globalThis`，可以使用以下命令。

```sh theme={"theme":{"light":"github-light","dark":"dracula"}}
bun --define global="globalThis" src/index.ts
```

`global` 是 Node.js 中的全局对象，但在浏览器中不是。因此，你可以用这个方法修正代码中假设 `global` 存在的情况。

### 使用 JSON 替换值

`--define` 也可以用来替换 JSON 对象和数组。

要将所有 `AWS` 替换为 JSON 对象 `{"ACCESS_KEY":"abc","SECRET_KEY":"def"}`，可以使用以下命令。

```sh theme={"theme":{"light":"github-light","dark":"dracula"}}
# JSON
bun --define AWS='{"ACCESS_KEY":"abc","SECRET_KEY":"def"}' src/index.ts
```

这些会被转换成等价的 JavaScript 代码。

从：

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
console.log(AWS.ACCESS_KEY); // => "abc"
```

变成：

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
console.log("abc");
```

### 使用其他属性替换值

你也可以传递属性给 `--define` 标志。

例如，要将所有 `console.write` 替换成 `console.log`，可以使用以下命令：

```sh theme={"theme":{"light":"github-light","dark":"dracula"}}
bun --define console.write=console.log src/index.ts
```

这会将以下输入转换：

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
console.write("Hello, world!");
```

变成以下输出：

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
console.log("Hello, world!");
```

## 这和设置变量有什么不同？

你也可以在代码中将 `process.env.NODE_ENV` 设置为 `"production"`，但这不会有助于死代码消除。在 JavaScript 中，属性访问可能会有副作用。getter 和 setter 可能是函数，甚至是动态定义的（基于原型链和 Proxy）。即便你将 `process.env.NODE_ENV` 设置为 `"production"`，静态分析工具也不能在下一行假设 `process.env.NODE_ENV` 就是 `"production"`。

## 这和查找替换或字符串替换有什么不同？

`--define` 标志是在 AST（抽象语法树）级别进行操作，而不是文本级别。它发生在转译过程中，意味着它可以用于诸如死代码消除之类的优化。

字符串替换工具往往有转义问题，并且可能替换到代码中不应替换的部分。
