当前位置: 首页 > news >正文

Vite 双引擎架构 —— Esbuild 概念篇

Vite 底层采用 双引擎架构,核心构建引擎是 EsbuildRollup,二者在开发和生产环境中分工协作,共同实现高性能构建。不可否认,作为 Vite 的双引擎之一,Esbuild 在很多关键的构建阶段(如依赖预编译TS 语法转译代码压缩)让 Vite 获得了相当优异的性能,是 Vite 高性能的得力助手。无论是在 Vite 的配置项还是源码实现中,都包含了不少 Esbuild 本身的基本概念和高阶用法。因此,要深入掌握 Vite,学习 Esbuild 必不可少。

本篇文章我将由 Esbuild 开始,讲解 Vite 强大的双引擎结构。强烈建议上手操作,读两三遍,不如上手写一遍 。《esbuild 中文文档》

🔍 一、为什么 Esbuild 的性能极高?

极速构建:

  • 性能碾压传统工具:基于 Go 语言编写,多进程并行处理,比 Webpack/Rollup 快 10-100 倍(10个 three.js 副本打包仅需 0.39秒 vs Webpack 的 41秒) 。
  • 无缓存仍高效:内置优化算法,无需依赖缓存即可实现秒级编译 。
     

开箱即用的支持:

  • 语言支持:原生处理 JS、TS、JSX、CSS(含 CSS Modules),无需额外配置 。
  • 模块化:无缝捆绑 ESM 和 CommonJS 模块,自动树摇(Tree Shaking) 。
     

多场景适配:

  • 浏览器环境:默认输出浏览器兼容代码,支持 --minify 压缩、--sourcemap 源码映射 。
  • Node 环境:通过 --platform=node 打包,剥离 TS 类型、转换 ESM→CommonJS 。

 🛠️ 二、 Esbuild 安装与使用

npm install esbuild  # 或 yarn add esbuild

1. 命令行调用

命令行方式调用也是最简单的使用方式。我们先来写一些示例代码,新建src/index.jsx文件,内容如下:

import Server from "react-dom/server";let Greet = () => <h1>祝所有高三的同学,金榜题名!</h1>;
console.log(Server.renderToString(<Greet />));

注意安装一下所需的依赖,在终端执行如下的命令:

npm install react react-dom

接着到package.json中添加build脚本:

 "scripts": {"build": "esbuild src/index.jsx --bundle --outfile=dist/out.js",},

现在,你可以在终端执行npm run build,可以发现如下的日志信息:

接着我们就可以看到dish目录中的打包产物

 

说明我们已经成功通过命令行完成了 Esbuild 打包!但命令行的使用方式不够灵活,只能传入一些简单的命令行参数,稍微复杂的场景就不适用了,所以一般情况下我们还是会用代码调用的方式。

2. 代码调用

Esbuild 对外暴露了一系列的 API,主要包括两类: Build APITransform API,我们可以在 Nodejs 代码中通过调用这些 API 来使用 Esbuild 的各种功能。想要更全面的了解的,可以去访问文章开头的文档地址。

项目打包——Build API

Build API主要用来进行项目打包,包括buildbuildSync和 serve三个方法。

A、build 方法:异步打包

功能:执行异步构建任务,返回 Promise 对象,支持插件和并行操作。

适用场景:生产环境打包、复杂构建流程(如代码分割、压缩)。

首先我们来试着在 Node.js 中使用build 方法。你可以在项目根目录新建build.js文件,内容如下:

import { build } from 'esbuild';async function runBuild() {// 异步方法,返回一个 Promiseconst result = await build({// ----  如下是一些常见的配置  --- // 当前项目根目录absWorkingDir: process.cwd(),// 入口文件列表,为一个数组entryPoints: ["./src/index.jsx"],// 打包产物目录outdir: "dist",// 是否需要打包,一般设为 truebundle: true,// 模块格式,包括`esm`、`commonjs`和`iife`format: "esm",// 需要排除打包的依赖列表external: [],// 是否开启自动拆包splitting: true,// 是否生成 SourceMap 文件sourcemap: true,// 是否生成打包的元信息文件metafile: true,// 是否进行代码压缩minify: false,// 是否开启 watch 模式,在 watch 模式下代码变动则会触发重新打包watch: false,// 是否将产物写入磁盘write: true,// Esbuild 内置了一系列的 loader,包括 base64、binary、css、dataurl、file、js(x)、ts(x)、text、json// 针对一些特殊的文件,调用不同的 loader 进行加载loader: {'.png': 'base64',}});console.log(result);
}runBuild();

随后,你在命令行执行node build.js,就能在控制台发现如下日志信息:

接着我们就可以看到dish目录中的打包产物和相应的 SourceMap 文件

 

B、buildSync 方法:同步打包 (不推荐)

功能:同步执行构建任务,立即返回结果,但阻塞主线程

适用场景:小型项目、简单脚本或 CLI 工具。

一个简单的例子:

const result = esbuild.buildSync({entryPoints: ['app.js'],bundle: true,outfile: 'out.js',platform: 'node' // 指定 Node 环境
});if (result.errors.length > 0) {throw new Error('Build failed');
}

局限性

  • 性能影响:阻塞主线程,可能导致界面卡顿
  • 插件限制:Rollup 等工具的 buildSync 不支持插件
  • 适用性:仅推荐在轻量任务中使用

难道就不能使用同步打包了吗??          如果说有,其实也是有的

使用 build + await 实现伪同步:

async function runBuild() {await esbuild.build({ /* 配置 */ });
}

 

C、serve 方法:开发服务器

这个 API 有 3 个特点。

  1. 开启 serve 模式后,将在指定的端口和目录上搭建一个静态文件服务,这个服务器用原生 Go 语言实现,性能比 Nodejs 更高。

  2. 类似 webpack-dev-server,所有的产物文件都默认不会写到磁盘,而是放在内存中,通过请求服务来访问。

  3. 每次请求到来时,都会进行重新构建(rebuild),永远返回新的产物。

下面,我们通过一个具体例子来感受一下。

// build.js
import { serve } from 'esbuild';function runBuild() {serve({port: 8000,servedir: './dist',onRequest: (args) => {if (args.path === '/') {args.path = '/index.html'}}},{absWorkingDir: process.cwd(),entryPoints: ["./src/index.jsx"],bundle: true,format: "esm",splitting: true,sourcemap: true,outdir: "dist",loader: {'.js': 'jsx','.png': 'file','.jpg': 'file'}}).then((server) => {console.log("HTTP Server starts at port", server.port);});
}runBuild();

1.运行构建命令

npm run build

2.启动服务器

node build.js

我们在浏览器访问http://localhost:8000/dist/index.js可以看到 Esbuild 服务器返回的编译产物如下所示:

后续每次在浏览器请求都会触发 Esbuild 重新构建,而每次重新构建都是一个增量构建的过程,耗时也会比首次构建少很多(一般能减少 70% 左右)。

Serve API 只适合在开发阶段使用,不适用于生产环境。

单文件转译——Transform API

功能:对单个字符串内容进行转换(如转译 TS/JSX),不访问文件系统,适用于非文件环境(如浏览器内联处理)或作为工具链一环。

Build API 类似,它也包含了同步和异步的两个方法,分别是transformSynctransform

举例栗子:在项目根目录新建transform.js

// transform.js
import { transform, transformSync } from 'esbuild';async function runTransform() {// 第一个参数是代码字符串,第二个参数为编译配置const content = await transform("const isNull = (str: string): boolean => str.length > 0;",{sourcemap: true,loader: "tsx",});console.log(content);
}runTransform();

终端输入:

node transform.js

接着你就会看见:

同样的步骤,传参:

// transform.js
import { transform, transformSync } from 'esbuild';async function runTransform(code = "const isNull = (str: string): boolean => str.length > 0;") {// 第一个参数是代码字符串,第二个参数为编译配置const content = await transform(code,{sourcemap: true,loader: "tsx",});console.log(content);
}const inputCode = process.argv[2];
runTransform(inputCode).catch(console.error);

终端输入:

node transform.js "const add = (a: number, b: number): number => a + b;"

打印出:

由于同步的 API 会使 Esbuild 丧失并发任务处理的优势(Build API的部分已经分析过),我同样也不推荐大家使用transformSync。出于性能考虑,Vite 的底层实现也是采用 transform这个异步的 API 进行 TS 及 JSX 的单文件转译的。

📊 三、总结

Esbuild的优势在于编译速度非常快,且拥有Go语言的优势,Go语言编写的程序比JavaScript少了一个动态解释的过程;在代码实现上,Esbuild使用比较克制,很多在Webpack上使用插件实现的功能如loader、minify等均使用Go实现。;劣势在于支持不完善,提供的功能很基础,对代码分割和css处理等支持较弱。

✅ 优势
  • 速度为王:Go 语言 + 并行处理 + 内置功能(减少 AST 转换链) 。
     
  • 轻量 API:提供 CLI、JS、Go 三种接口,配置简洁 。
     
  • 生产优化:默认支持 Tree Shaking、代码压缩、Source Map 。
❌ 局限性

1.生态插件较弱

  • 不支持 Vue/Sass/Less 等语法,需 JS 插件(性能下降) 。
  • 无热更新(HMR),依赖 --watch 或手动重启 。

2.高级功能缺失

  • 无 AST 操作接口,无法实现类 Babel 按需引入 。
  • 代码分割(Code Splitting)对非 ESM 包支持差 。
     

但是不可否认,它的作用和潜力,我相信 Esbuild 未来在持续迭代中, 生态完善后或颠覆前端构建范式。

相关文章:

  • Self Attention自注意力机制
  • 使用 Docker Compose 从零部署 TeamCity + PostgreSQL(详细新手教程)
  • Ubuntu 系统通过防火墙管控 Docker 容器
  • 【PyQt5】用于设置控件位置的参数
  • 【Kotlin】注解反射扩展
  • [大A量化专栏] 夏普比率
  • Linux 下的COW机制(copy-on-write)
  • android app 一个 crash的解决过程!
  • 26.【新型数据架构】-零ETL架构
  • python打卡day46@浙大疏锦行
  • 【驱动】Orin NX恢复备份失败:does not match the current board you‘re flashing onto
  • 数列运算中的常见错因分析
  • java学习电子书推荐
  • 密码学基础——SM4算法
  • 408第一季 - 数据结构 - 栈与队列的应用
  • Cesium等高线
  • 【GESP真题解析】第 14 集 GESP 三级 2024 年 9 月编程题 1:平衡序列
  • Python打卡第46天
  • 猜字符位置游戏-position gasses
  • STM32标准库-TIM输出比较
  • 修改网站搜索缩略图/关键词排名优化公司哪家好
  • 十大免费ppt网站流氓下载/注册网站怎么注册
  • 如何做企业网站规划/seo外包
  • 关于网站开发论文参考文献/百度搜索引擎网址
  • 专业做曝光引流网站/seo3的空间构型
  • 网站统计代码/台州seo