什么是 Esbuild?
Esbuild 是由 Figma 的 CTO 「Evan Wallace」基于 Golang 开发的一款打包工具,相比传统的打包工具,主打性能优势,在构建速度上可以快 10~100 倍。
受够了webpack
缓慢的打包速度,越来越多的团队开始探索采用更加底层的语言来编写前端的打包工具,以此来突破JavaScript语言的瓶颈。
esbuild
便是其中非常具有代表性的工具之一,它采用Go
语言编写,经过了vite
和nest.js
的检验,开创了构建工具性能的新时代。
其主要特点:
- 无需缓存即可实现极高的速度
- 内置JavaScript、CSS、TypeScript``和JSX
- 直接用于CLI、JS和Go的API
- 打包ESM和CommonJS模块
- 打包CSS,包括CSS modules
- Tree shaking, minification, source maps
- Local server, watch mode, plugins

esbuild中文文档
Esbuild架构优势
1. Golang 开发
采用 Go 语言开发,相比于 单线程 + JIT 性质的解释型语言 ,使用 Go 的优势在于 :
一方面可以充分利用多线程打包,并且线程之间共享内容,而 JS 如果使用多线程还需要有线程通信(postMessage)的开销;
另一方面直接编译成机器码,而不用像 Node 一样先将 JS 代码解析为字节码,然后转换为机器码,大大节省了程序运行时间。
2. 多核并行
内部打包算法充分利用多核 CPU 优势。Esbuild 内部算法设计是经过精心设计的,尽可能充分利用所有的 CPU 内核。所有的步骤尽可能并行,这也是得益于 Go 当中多线程共享内存的优势,而在 JS 中所有的步骤只能是串行的。
3. 从零造轮子
从零开始造轮子,没有任何第三方库的黑盒逻辑,保证极致的代码性能。
- 高效利用内存
一般而言,在 JS 开发的传统打包工具当中一般会频繁地解析和传递 AST 数据,比如 string -> TS -> JS -> string,这其中会涉及复杂的编译工具链,比如 webpack -> babel -> terser,每次接触到新的工具链,都得重新解析 AST,导致大量的内存占用。而 Esbuild 中从头到尾尽可能地复用一份 AST 节点数据,从而大大提高了内存的利用效率,提升编译性能。
esbuild 与传统工具的对比
特性 | esbuild | Webpack | Rollup |
---|---|---|---|
构建速度 | 极快(10-100 倍) | 较慢 | 较快 |
配置复杂度 | 简单 | 复杂 | 中等 |
插件系统 | 灵活 | 非常灵活 | 灵活 |
支持的文件格式 | JS、TS、JSX、CSS | 多种格式(需插件支持) | JS、TS、JSX |
社区生态 | 较小 | 非常成熟 | 成熟 |
使用场景
1. 小型项目
对于小型项目,esbuild 的极速构建和简洁配置使其成为理想选择。开发者可以快速完成项目的打包工作,无需复杂的配置。
2. 大型项目
对于大型项目,esbuild 的并行处理能力和插件系统可以显著提升构建效率。虽然 esbuild 的社区生态不如 Webpack 成熟,但其性能优势足以弥补这一不足。
3. 前端框架项目
esbuild 支持 JSX 和 TypeScript,非常适合用于 React、Vue 等前端框架项目。通过插件系统,可以轻松扩展其功能,满足复杂项目的需求。
安装 esbuild
在使用 esbuild 之前,首先需要安装它。你可以通过 npm 或 yarn 来安装 esbuild:
bash
npm install esbuild --save-dev
或
yarn add esbuild --dev
使用 esbuild 打包 JavaScript 文件
首先,创建一个简单的项目结构:
javascript
my-project/
├── src/
│ └── index.js
└── package.json
在 src/index.js 文件中,添加一些简单的 JavaScript 代码:
javascript
// src/index.js
console.log("Hello, esbuild!");
接下来,我们编写一个简单的 esbuild 配置文件,用于打包 src/index.js 文件。
在项目根目录下创建一个 build.js
文件,内容如下:
编写 esbuild 配置
javascript
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/index.js'],
outfile: 'dist/bundle.js',
bundle: true,
minify: true,
sourcemap: true,
}).catch(() => process.exit(1));
在这个配置中:
- entryPoints:指定入口文件,即 src/index.js。
- outfile:指定输出文件的路径,即 dist/bundle.js。
- bundle:设置为 true,表示将所有依赖打包到一个文件中。
- minify:设置为 true,表示对输出文件进行压缩。
- sourcemap:设置为 true,表示生成 source map 文件,方便调试。
运行打包命令
在终端中运行以下命令来执行打包:
bash
node build.js
运行完成后,你会在 dist 目录下看到生成的 bundle.js
文件。
验证打包结果
你可以通过在浏览器中打开一个简单的 HTML 文件来验证打包结果。在项目根目录下创建一个 index.html 文件,内容如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>esbuild Example</title>
</head>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
在浏览器中打开 index.html,你应该会在控制台中看到 Hello, esbuild! 的输出。
esbuild高级功能:使用插件
esbuild 支持插件机制,允许你通过插件来扩展其功能。例如,你可以使用插件来处理 CSS、图片、TypeScript 等资源。
安装插件
假设我们想要使用 esbuild-sass-plugin 来处理 Sass 文件,首先需要安装该插件:
bash
npm install esbuild-sass-plugin --save-dev
修改配置文件
接下来,修改 build.js 文件,添加 Sass 插件:
javascript
const esbuild = require('esbuild');
const sassPlugin = require('esbuild-sass-plugin');
esbuild.build({
entryPoints: ['src/index.js'],
outfile: 'dist/bundle.js',
bundle: true,
minify: true,
sourcemap: true,
plugins: [sassPlugin()],
}).catch(() => process.exit(1));
添加 Sass 文件
在 src 目录下创建一个 styles.scss 文件,内容如下:
js
// src/styles.scss
body {
background-color: #f0f0f0;
h1 {
color: #333;
}
}
然后在 src/index.js 中引入这个 Sass 文件:
javascript
// src/index.js
import './styles.scss';
console.log("Hello, esbuild!");
打包完成后,dist/bundle.js 中将包含处理后的 CSS 代码。
总结
esbuild 作为一个新兴的 JavaScript 打包工具,以其极快的构建速度和简洁的 API 设计,迅速赢得了开发者的青睐。虽然它在社区生态和功能丰富度上还无法与 Webpack 等传统工具相比,但其性能优势使其成为小型项目和前端框架项目的理想选择。