--define 标志允许您声明静态可分析的常量和全局变量。它将 JavaScript 或 TypeScript 文件中的标识符或属性的所有使用替换为常量值。此功能在运行时和 bun build 中都受支持。这有点类似于 C/C++ 中的 #define,但适用于 JavaScript。
terminal
Bun 使用这些静态已知的值进行死代码消除和其他优化。
在代码到达 JavaScript 引擎之前,Bun 将
process.env.NODE_ENV 替换为 "production"。
不仅如此。Bun 的优化转译器足够智能,可以做一些基本的常量折叠。 由于
"production" === "production" 总是 true,Bun 将整个表达式替换为 true 值。
最后,Bun 检测到
else 分支无法访问,并将其消除。
支持哪些类型的值?
值可以是字符串、标识符、属性或 JSON。替换全局标识符
要使window 的所有使用都变为 undefined,您可以使用以下命令。
window 对象时非常有用。
global 的所有使用都变为 globalThis,您可以使用以下命令。
global 是 Node.js 中的一个全局对象,但在 Web 浏览器中不是。因此,您可以使用此方法来修复某些代码假定 global 可用的情况。
使用 JSON 替换值
--define 还可用于使用 JSON 对象和数组替换值。
要将 AWS 的所有使用替换为 JSON 对象 {"ACCESS_KEY":"abc","SECRET_KEY":"def"},您可以使用以下命令。
使用其他属性替换值
您还可以将属性传递给--define 标志。
例如,要将 console.write 的所有使用替换为 console.log,您可以使用以下命令
这与设置变量有何不同?
您也可以在代码中将process.env.NODE_ENV 设置为 "production",但这对死代码消除没有帮助。在 JavaScript 中,属性访问可能有副作用。Getter & Setter 可以是函数,甚至可以动态定义(由于原型链和 Proxy)。即使您将 process.env.NODE_ENV 设置为 "production",在下一行,对于静态分析工具来说,假设 process.env.NODE_ENV 是 "production" 也是不安全的。
这与查找替换或字符串替换有何不同?
--define 标志在 AST(抽象语法树)级别操作,而不是在文本级别操作。它发生在转译过程中,这意味着它可以用于死代码消除等优化。
字符串替换工具往往有转义问题,并替换代码的非预期部分。