> ## Documentation Index
> Fetch the complete documentation index at: https://bun.ll1025.cn/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={null}
bun --define process.env.NODE_ENV="'production'" src/index.ts # 运行时
bun build --define process.env.NODE_ENV="'production'" src/index.ts # 构建
```

***

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

```ts theme={null}
if (process.env.NODE_ENV === "production") {
  console.log("生产模式");
} else {
  console.log("开发模式");
}
```

***

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

```ts theme={null}
if ("production" === "production") { // [!code ++]
  console.log("生产模式");
} else {
  console.log("开发模式");
}
```

***

Bun 的优化转译器还会进行基本的常量折叠。

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

```ts theme={null}
if (true) { // [!code ++]
  console.log("生产模式");
}
```

***

要进一步将外围的 `if` 框架折叠为以下输出，请传入 `--minify-syntax`（也由 `--minify` 启用）：

```sh terminal icon="terminal" theme={null}
bun build --define process.env.NODE_ENV="'production'" --minify-syntax src/index.ts
```

```ts theme={null}
console.log("生产模式");
```

***

## 支持哪些类型的值？

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

### 替换全局标识符

将所有 `window` 的使用替换为 `undefined`：

```sh theme={null}
bun --define window="undefined" src/index.ts
```

这对于服务端渲染（SSR）很有用，或者确保代码不依赖于 `window` 对象。

```js theme={null}
if (typeof window !== "undefined") {
  console.log("客户端代码");
} else {
  console.log("服务端代码");
}
```

该值也可以是另一个标识符。例如，将所有 `global` 的使用替换为 `globalThis`：

```sh theme={null}
bun --define global="globalThis" src/index.ts
```

`global` 是 Node.js 中的全局对象，但在 Web 浏览器中不是，因此此替换可修复假定 `global` 可用的代码。

### 用 JSON 替换值

`--define` 还可以用 JSON 对象和数组替换值。

要将所有 `AWS` 的使用替换为 JSON 对象 `{"ACCESS_KEY":"abc","SECRET_KEY":"def"}`：

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

Bun 将这些转换为等效的 JavaScript 代码。

转换前：

```ts theme={null}
console.log(AWS.ACCESS_KEY); // => "abc"
```

转换后：

```ts theme={null}
console.log({ ACCESS_KEY: "abc", SECRET_KEY: "def" }.ACCESS_KEY);
```

### 用其他属性替换值

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

例如，将所有 `console.write` 的使用替换为 `console.log`：

```sh theme={null}
bun --define console.write=console.log src/index.ts
```

这会将以下输入：

```ts theme={null}
console.write("Hello, world!");
```

转换为以下输出：

```ts theme={null}
console.log("Hello, world!");
```

## 这与设置变量有何不同？

你也可以在代码中将 `process.env.NODE_ENV` 设置为 `"production"`，但这无助于死代码消除。在 JavaScript 中，属性访问可能有副作用。Getter 和 setter 可以是函数，甚至可以是动态定义的（由于原型链和 Proxy）。即使你将 `process.env.NODE_ENV` 设置为 `"production"`，静态分析工具也无法保证它在下一行仍然是 `"production"`。

## 这与查找替换或字符串替换有何不同？

`--define` 标志操作的是 AST（抽象语法树），而不是文本。替换在转译期间发生，因此它参与诸如死代码消除之类的优化。

字符串替换工具往往存在转义问题，并可能替换代码中不打算被替换的部分。
