Skip to main content
--define 标志用于声明可静态分析的常量和全局变量。它会将 JavaScript 或 TypeScript 文件中标识符或属性的所有用法替换为常量值,并且在运行时和 bun build 中均可使用。它类似于 C/C++ 中的 #define,但适用于 JavaScript。
terminal

Bun 会利用这些静态已知值来消除无效代码并执行其他优化。

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

Bun 的优化型转译器也会执行基本的常量折叠。 由于 "production" === "production" 始终为 true,Bun 会将整个表达式替换为 true 值,并移除不可达的 else 分支。

若还要将周围的 if 框架折叠为以下输出,请传入 --minify-syntax--minify 也会启用该选项):
terminal

支持哪些类型的值?

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

替换全局标识符

将所有 window 的使用替换为 undefined
这对于服务器端渲染(SSR)很有用,也可以确保代码不依赖 window 对象。
该值也可以是另一个标识符。例如,将所有 global 的使用替换为 globalThis
global 是 Node.js 中的全局对象,但在 Web 浏览器中并不是,因此此替换可以修复假设 global 可用的代码。

使用 JSON 替换值

--define 也可以将值替换为 JSON 对象和数组。 将所有 AWS 的使用替换为 JSON 对象 {"ACCESS_KEY":"abc","SECRET_KEY":"def"}
Bun 会将这些内容转换为等效的 JavaScript 代码。 从:
变成:

使用其他属性替换值

你也可以传递属性给 --define 标志。 例如,将所有 console.write 的使用替换为 console.log
这会将以下输入转换:
变成以下输出:

这和设置变量有什么不同?

你也可以在代码中将 process.env.NODE_ENV 设置为 "production",但这并不能帮助消除无效代码。在 JavaScript 中,属性访问可能具有副作用。Getter 和 setter 可以是函数,甚至可以动态定义(由于原型链和 Proxy)。即使你将 process.env.NODE_ENV 设置为 "production",静态分析工具也不能假定下一行中它仍然是 "production"

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

--define 标志操作的是 AST(抽象语法树),而不是文本。替换发生在转译过程中,因此可以参与死代码消除等优化。 字符串替换工具往往有转义问题,并且可能替换到代码中不应替换的部分。