# esbuild
# esubuild 为什么快 (vite 选择 esbuild 在开发环境打包第三方依赖的原因)
- 使用 Go 开发
Go 的代码会被直接编译成原生机器码,而不需要像 JS 一样先解析为字节码,然后再转换成字节码,大大的节省了程序运行的时间、 - 多核并行
因为 Go 中多线程共享内存的优势,内部打包算法充分的利用了多核 CPU 的多核优势,使得所有步骤尽可能的并行 - 从零造轮子
几乎没有使用第三方库,全部是自己编写的逻辑,保证了代码的极致性能 - 高效的内存利用
Esbuild 中从头到尾尽可能地复用一份 AST 节点数据,而不用像 JS 打包工具中频繁地解析和传递 AST 数据(如 string -> TS -> JS -> string),造成内存的大量浪费。
# esbuild 的不足(vite 为什么在生产环境不选择 esbuild 而选择了 rollup 来进行打包)
- 无法兼容低端浏览器
不支持把语法降级到es5
,不支持const enum
等高级语法 - 无法灵活处理打包产物,无法自定义拆包
没有提供操作打包产物的接口,没有提供子定义拆包策略的 api
# vite 用 esbuild 做了什么
- bunder
- 在开发环境,为了顺利的实现
no-bunder
,在预构建使用 esuild 来将其他的模块化规范转换成了esm
(因为no-bundler
本质上是利用了浏览器原生支持 esm,让浏览器来请求对应模块) - 使用 esbuild 来对第三方依赖进行打包(避免出现请求瀑布流,浏览器发起过多请求,导致首屏时间过长)
- 在开发环境,为了顺利的实现
- transformer
进行单文件编译,作为 TS, JSX, TSX 的编译工具,并且在生产环境也是用的 esbuild 来进行编译。但是无法进行 ts 的类型检查,所以还是需要利用tsc
来进行类型检查 - minifier
对 css, js 文件进行压缩
# rollup
# vite 用 rollup 做了什么
生产环境利用
rollup
进行打包,并对其进行扩展和优化- CSS 代码分割
如果某个异步模块中引入了一些 CSS 代码,Vite 就会自动将这些 CSS 抽取出来生成单独的文件,提高线上产物的缓存复用率。 - 自动预加载
Vite 会自动为入口 chunk 的依赖自动生成预加载标签<link rel="modulepreload">
- 异步 Chunk 加载优化
在异步引入的 Chunk 中,通常会有一些公用的模块,如现有两个 异 步引入的 Chunk: A 和 B,而且两者有一个公共依赖 C,一般 情况 下,Rollup 打包之后,会先请求 A,然后浏览器在加载 A 的过程 中才决定请求和加载 C,但 Vite 进行优化之后,请求 A 的同时会 自动预加载 C,通过优化 Rollup 产物依赖加载方式节省 了不必要 的网络开销。
- CSS 代码分割
兼容了
rollup
的插件机制
vite 插件可以直接传入 rollup 作为插件使用,但是 rollup 的插件不一定能直接传入 vite 作为 vite 插件使用