Bun 包含一个快速的 JavaScript 和 TypeScript 压缩器,可以将包大小减少 80% 或更多(取决于代码库),并使输出代码运行更快。压缩器执行数十种优化,包括常量折叠、死代码消除和语法转换。与其他压缩器不同,Bun 的压缩器使 bun build 运行更快,因为要打印的代码更少。
CLI 使用
启用所有压缩模式
使用 --minify 标志启用所有压缩模式:
bun build ./index.ts --minify --outfile=out.js--minify 标志自动启用:
- 空白压缩
- 语法压缩
- 标识符压缩
生产模式
--production 标志自动启用压缩:
bun build ./index.ts --production --outfile=out.js--production 标志还:
- 将
process.env.NODE_ENV设置为production - 启用生产模式 JSX 导入和转换
细粒度控制
您可以单独启用特定的压缩模式:
# 仅移除空白
bun build ./index.ts --minify-whitespace --outfile=out.js
# 仅压缩语法
bun build ./index.ts --minify-syntax --outfile=out.js
# 仅压缩标识符
bun build ./index.ts --minify-identifiers --outfile=out.js
# 组合特定模式
bun build ./index.ts --minify-whitespace --minify-syntax --outfile=out.jsJavaScript API
以编程方式使用 Bun 的打包器时,通过 minify 选项配置压缩:
await Bun.build({
entrypoints: ["./index.ts"],
outdir: "./out",
minify: true, // 启用所有压缩模式
});对于细粒度控制,传递对象:
await Bun.build({
entrypoints: ["./index.ts"],
outdir: "./out",
minify: {
whitespace: true,
syntax: true,
identifiers: true,
},
});压缩模式
Bun 的压缩器有三种独立的模式,可以单独启用或组合使用。
空白压缩(--minify-whitespace)
从输出中移除所有不必要的空白、换行和格式。
语法压缩(--minify-syntax)
将 JavaScript 语法重写为更短的等效形式,并执行常量折叠、死代码消除和其他优化。
标识符压缩(--minify-identifiers)
使用基于频率的优化将局部变量和函数名重命名为更短的标识符。
所有转换
布尔字面量缩短
模式: --minify-syntax
将布尔字面量转换为更短的表达式。
true
false!0
!1布尔代数优化
模式: --minify-syntax
使用逻辑规则简化布尔表达式。
!!x
x === true
x && true
x || false
!true
!falsex
x
x
x
!1
!0undefined 缩短
模式: --minify-syntax
将 undefined 替换为更短的等效形式。
undefined
let x = undefined;void 0
let x=void 0;undefined 相等优化
模式: --minify-syntax
优化与 undefined 的松散相等检查。
x == undefined
x != undefinedx == null
x != nullInfinity 缩短
模式: --minify-syntax
将 Infinity 转换为数学表达式。
Infinity
-Infinity1/0
-1/0Typeof 优化
模式: --minify-syntax
优化 typeof 比较并评估常量 typeof 表达式。
typeof x === 'undefined'
typeof x !== 'undefined'
typeof require
typeof null
typeof true
typeof 123
typeof "str"
typeof 123ntypeof x>'u'
typeof x<'u'
"function"
"object"
"boolean"
"number"
"string"
"bigint"数字格式化
模式: --minify-syntax
以最紧凑的表示形式格式化数字。
10000
100000
1000000
1.0
-42.01e4
1e5
1e6
1
-42算术常量折叠
模式: --minify-syntax
在编译时评估算术运算。
1 + 2
10 - 5
3 * 4
10 / 2
10 % 3
2 ** 33
5
12
5
1
8位运算常量折叠
模式: --minify-syntax
在编译时评估位运算。
5 & 3
5 | 3
5 ^ 3
8 << 2
32 >> 2
~51
7
6
32
8
-6字符串连接
模式: --minify-syntax
在编译时组合字符串字面量。
"a" + "b"
"x" + 123
"foo" + "bar" + "baz""ab"
"x123"
"foobarbaz"字符串索引
模式: --minify-syntax
在编译时评估字符串字符访问。
"foo"[2]
"hello"[0]"o"
"h"模板字面量折叠
模式: --minify-syntax
评估带有常量表达式的模板字面量。
`a${123}b`
`result: ${5 + 10}`"a123b"
"result: 15"模板字面量转换为字符串
模式: --minify-syntax
将简单模板字面量转换为常规字符串。
`Hello World`
`Line 1
Line 2`"Hello World"
"Line 1\nLine 2"字符串引号优化
模式: --minify-syntax
选择最佳引号字符以最小化转义。
"It's a string"
'He said "hello"'
`Simple string`"It's a string"
'He said "hello"'
"Simple string"数组展开内联
模式: --minify-syntax
内联带有常量数组的数组展开操作。
[1, ...[2, 3], 4]
[...[a, b]][1,2,3,4]
[a,b]数组索引
模式: --minify-syntax
在编译时评估常量数组访问。
[x][0]
['a', 'b', 'c'][1]
['a', , 'c'][1]x
'b'
void 0属性访问优化
模式: --minify-syntax
在可能时将方括号表示法转换为点表示法。
obj["property"]
obj["validName"]
obj["123"]
obj["invalid-name"]obj.property
obj.validName
obj["123"]
obj["invalid-name"]比较折叠
模式: --minify-syntax
在编译时评估常量比较。
3 < 5
5 > 3
3 <= 3
5 >= 6
"a" < "b"!0
!0
!0
!1
!0逻辑运算折叠
模式: --minify-syntax
使用常量值简化逻辑运算。
true && x
false && x
true || x
false || xx
!1
!0
x空值合并折叠
模式: --minify-syntax
评估具有已知值的空值合并。
null ?? x
undefined ?? x
42 ?? xx
x
42逗号表达式简化
模式: --minify-syntax
从逗号序列中移除无副作用的表达式。
(0, x)
(123, "str", x)x
x三元条件折叠
模式: --minify-syntax
评估具有常量条件的条件表达式。
true ? a : b
false ? a : b
x ? true : false
x ? false : truea
b
x ? !0 : !1
x ? !1 : !0一元表达式折叠
模式: --minify-syntax
简化一元运算。
+123
+"123"
-(-x)
~~x
!!x123
123
123
123
x
~~x
!!x
x双重否定移除
模式: --minify-syntax
移除不必要的双重否定。
!!x
!!!xx
!xif 语句优化
模式: --minify-syntax
优化具有常量条件的 if 语句。
if (true) x;
if (false) x;
if (x) { a; }
if (x) {} else y;x;
// 已移除
if(x)a;
if(!x)y;死代码消除
模式: --minify-syntax
移除不可达代码和无副作用的代码。
if (false) {
unreachable();
}
function foo() {
return x;
deadCode();
}function foo(){return x}不可达分支移除
模式: --minify-syntax
移除永远不会执行的分支。
while (false) {
neverRuns();
}// 完全移除空块移除
模式: --minify-syntax
移除空块和不必要的大括号。
{ }
if (x) { };
// 已移除单语句块展开
模式: --minify-syntax
移除单个语句周围不必要的大括号。
if (condition) {
doSomething();
}if(condition)doSomething();TypeScript 枚举内联
模式: --minify-syntax
在编译时内联 TypeScript 枚举值。
enum Color { Red, Green, Blue }
const x = Color.Red;const x=0;纯注释支持
模式: 始终激活
尊重 /*@__PURE__*/ 注释用于 tree shaking。
const x = /*@__PURE__*/ expensive();
// 如果 x 未使用...// 完全移除标识符重命名
模式: --minify-identifiers
根据使用频率将局部变量重命名为更短的名称。
function calculateSum(firstNumber, secondNumber) {
const result = firstNumber + secondNumber;
return result;
}function a(b,c){const d=b+c;return d}命名策略:
- 最常用的标识符获得最短的名称(a、b、c...)
- 单个字母:a-z(26 个名称)
- 双字母:aa-zz(676 个名称)
- 三字母及更多按需使用
保留的标识符:
- JavaScript 关键字和保留字
- 全局标识符
- 命名导出(维护 API)
- CommonJS 名称:
exports、module
空白移除
模式: --minify-whitespace
移除所有不必要的空白。
function add(a, b) {
return a + b;
}
let x = 10;function add(a,b){return a+b;}let x=10;分号优化
模式: --minify-whitespace
仅在必要时插入分号。
let a = 1;
let b = 2;
return a + b;let a=1;let b=2;return a+b运算符间距移除
模式: --minify-whitespace
移除运算符周围的空格。
a + b
x = y * z
foo && bar || baza+b
x=y*z
foo&&bar||baz注释移除
模式: --minify-whitespace
移除注释,重要的许可证注释除外。
// 此注释被移除
/* 此注释也被移除 */
/*! 但此许可证注释保留 */
function test() { /* 内联注释 */ }/*! 但此许可证注释保留 */
function test(){}对象和数组格式化
模式: --minify-whitespace
移除对象和数组字面量中的空白。
const obj = {
name: "John",
age: 30
};
const arr = [1, 2, 3];const obj={name:"John",age:30};const arr=[1,2,3];控制流格式化
模式: --minify-whitespace
移除控制结构中的空白。
if (condition) {
doSomething();
}
for (let i = 0; i < 10; i++) {
console.log(i);
}if(condition)doSomething();for(let i=0;i<10;i++)console.log(i);函数格式化
模式: --minify-whitespace
移除函数声明中的空白。
function myFunction(param1, param2) {
return param1 + param2;
}
const arrow = (a, b) => a + b;function myFunction(a,b){return a+b}const arrow=(a,b)=>a+b;括号最小化
模式: 始终激活
仅在运算符优先级需要时添加括号。
(a + b) * c
a + (b * c)
((x))(a+b)*c
a+b*c
x属性混淆
模式: --minify-identifiers(带配置)
在配置时将对象属性重命名为更短的名称。
obj.longPropertyNameobj.a模板字面量值折叠
模式: --minify-syntax
将非字符串插值值转换为字符串并折叠到模板中。
`hello ${123}`
`value: ${true}`
`result: ${null}`
`status: ${undefined}`
`big: ${10n}`"hello 123"
"value: true"
"result: null"
"status: undefined"
"big: 10"字符串长度常量折叠
模式: --minify-syntax
在编译时评估字符串字面量上的 .length 属性。
"hello world".length
"test".length11
4构造函数调用简化
模式: --minify-syntax
简化内置类型的构造函数调用。
new Object()
new Object(null)
new Object({a: 1})
new Array()
new Array(x, y){}
{}
{a:1}
[]
[x,y]单属性对象内联
模式: --minify-syntax
内联具有单个属性的对象的属性访问。
({fn: () => console.log('hi')}).fn()(() => console.log('hi'))()字符串 charCodeAt 常量折叠
模式: 始终激活
评估字符串字面量上的 charCodeAt() 用于 ASCII 字符。
"hello".charCodeAt(1)
"A".charCodeAt(0)101
65Void 0 相等转换为 null 相等
模式: --minify-syntax
将与 void 0 的松散相等检查转换为 null,因为它们是等效的。
x == void 0
x != void 0x == null
x != null否定运算符优化
模式: --minify-syntax
将否定运算符移过逗号表达式。
-(a, b)
-(x, y, z)a,-b
x,y,-zImport.meta 属性内联
模式: 打包模式
在构建时在值已知时内联 import.meta 属性。
import.meta.dir
import.meta.file
import.meta.path
import.meta.url"/path/to/directory"
"filename.js"
"/full/path/to/file.js"
"file:///full/path/to/file.js"变量声明合并
模式: --minify-syntax
合并相同类型的相邻变量声明。
let a = 1;
let b = 2;
const c = 3;
const d = 4;let a=1,b=2;
const c=3,d=4;表达式语句合并
模式: --minify-syntax
使用逗号运算符合并相邻表达式语句。
console.log(1);
console.log(2);
console.log(3);console.log(1),console.log(2),console.log(3);return 语句合并
模式: --minify-syntax
使用逗号运算符合并 return 之前的表达式。
console.log(x);
return y;return console.log(x),y;throw 语句合并
模式: --minify-syntax
使用逗号运算符合并 throw 之前的表达式。
console.log(x);
throw new Error();throw(console.log(x),new Error());TypeScript 枚举跨模块内联
模式: --minify-syntax(打包模式)
跨模块边界内联枚举值。
// lib.ts
export enum Color { Red, Green, Blue }
// 输入 (main.ts)
import { Color } from './lib';
const x = Color.Red;const x=0;计算属性枚举内联
模式: --minify-syntax
内联用作计算对象属性的枚举值。
enum Keys { FOO = 'foo' }
const obj = { [Keys.FOO]: value }const obj={foo:value}字符串数字转换为数字索引
模式: --minify-syntax
将字符串数字属性访问转换为数字索引。
obj["0"]
arr["5"]obj[0]
arr[5]箭头函数体缩短
模式: 始终激活
当箭头函数仅返回值时使用表达式体语法。
() => { return x; }
(a) => { return a + 1; }() => x
a => a + 1对象属性简写
模式: 始终激活
当属性名和值标识符匹配时使用简写语法。
{ x: x, y: y }
{ name: name, age: age }{ x, y }
{ name, age }方法简写
模式: 始终激活
在对象字面量中使用方法简写语法。
{
foo: function() {},
bar: async function() {}
}{
foo() {},
async bar() {}
}移除 debugger 语句
模式: --drop=debugger
从代码中移除 debugger 语句。
function test() {
debugger;
return x;
}function test(){return x}移除 console 调用
模式: --drop=console
从代码中移除所有 console.* 方法调用。
console.log("debug");
console.warn("warning");
x = console.error("error");void 0;
void 0;
x=void 0;移除自定义函数调用
模式: --drop=<name>
移除对指定全局函数或方法的调用。
assert(condition);
obj.assert(test);void 0;
void 0;保留名称
压缩标识符时,您可能希望保留原始函数和类名以便调试。使用 --keep-names 标志:
bun build ./index.ts --minify --keep-names --outfile=out.js或在 JavaScript API 中:
await Bun.build({
entrypoints: ["./index.ts"],
outdir: "./out",
minify: {
identifiers: true,
keepNames: true,
},
});这在仍然压缩代码中实际标识符名称的同时保留函数和类上的 .name 属性。
组合示例
一起使用所有三种压缩模式:
const myVariable = 42;
const myFunction = () => {
const isValid = true;
const result = undefined;
return isValid ? myVariable : result;
};
const output = myFunction();// 使用 --minify 输出(49 字节,减少 69%)
const a=42,b=()=>{const c=!0,d=void 0;return c?a:d},e=b();何时使用压缩
使用 --minify:
- 生产包
- 减少 CDN 带宽成本
- 提高页面加载时间
使用单独模式:
--minify-whitespace: 快速减小大小而不进行语义更改--minify-syntax: 更小的输出同时保持可读标识符以便调试--minify-identifiers: 最大程度减小大小(与--keep-names组合以获得更好的堆栈跟踪)
避免压缩:
- 开发构建(更难调试)
- 当您需要可读错误消息时
- 消费者可能阅读源代码的库