长沙网站设计报价,wordpress视频会员,保险官网查询,网站备案要拍照Vite 底层采用 双引擎架构#xff0c;核心构建引擎是 Esbuild 和 Rollup#xff0c;二者在开发和生产环境中分工协作#xff0c;共同实现高性能构建。不可否认#xff0c;作为 Vite 的双引擎之一#xff0c;Esbuild 在很多关键的构建阶段(如依赖预编译、TS 语法转译、代码…Vite 底层采用 双引擎架构核心构建引擎是 Esbuild 和 Rollup二者在开发和生产环境中分工协作共同实现高性能构建。不可否认作为 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 环境通过 --platformnode 打包剥离 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 --outfiledist/out.js,},
现在你可以在终端执行npm run build可以发现如下的日志信息: 接着我们就可以看到dish目录中的打包产物 说明我们已经成功通过命令行完成了 Esbuild 打包但命令行的使用方式不够灵活只能传入一些简单的命令行参数稍微复杂的场景就不适用了所以一般情况下我们还是会用代码调用的方式。
2. 代码调用
Esbuild 对外暴露了一系列的 API主要包括两类: Build API和Transform API我们可以在 Nodejs 代码中通过调用这些 API 来使用 Esbuild 的各种功能。想要更全面的了解的可以去访问文章开头的文档地址。
项目打包——Build API
Build API主要用来进行项目打包包括build、buildSync和 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和iifeformat: 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 个特点。 开启 serve 模式后将在指定的端口和目录上搭建一个静态文件服务这个服务器用原生 Go 语言实现性能比 Nodejs 更高。 类似 webpack-dev-server所有的产物文件都默认不会写到磁盘而是放在内存中通过请求服务来访问。 每次请求到来时都会进行重新构建(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 类似它也包含了同步和异步的两个方法分别是transformSync和transform。
举例栗子在项目根目录新建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 未来在持续迭代中 生态完善后或颠覆前端构建范式。