双引擎?
Esbuild和Rollup
性能利器 Esbuild
项目中的node_modules动辄就是几百MB 或 上GB,如果这些依赖在 vite 中使用就会存在 ESM 格式兼容性问题与海量请求的问题。对于依赖,是需要在应用启动前进行打包并转为 ESM 格式
当然,Esbuild 作为打包工具也有一些缺点。
- 不支持降级到 ES5 的代码。这意味着在低端浏览器代码会跑不起来。
- 不支持 const enum 等语法。这意味着单独使用这些语法在 esbuild 中会直接抛错。
- 不提供操作打包产物的接口,像 Rollup 中灵活处理打包产物的能力(如renderChunk钩子)在 Esbuild 当中完全没有。
- 不支持自定义 Code Splitting 策略。传统的 Webpack 和 Rollup 都提供了自定义拆包策略的 API,而 Esbuild 并未提供,从而降级了拆包优化的灵活性。
构建基石头 Rollup
vite 默认生产环境使用 Rollup 进行打包
- CSS 代码分割。如果某个异步模块中引入了一些 CSS 代码,Vite 就会自动将这些 CSS 抽取出来生成单独的文件,提高线上产物的缓存复用率。
- 自动预加载。Vite 会自动为入口 chunk 的依赖自动生成预加载标签
- 异步 Chunk 加载优化,当引入模块 A 与 B,他们都依赖一个模块 C 时,通常情况是在引入 A 的时候再请求 C,但 Vite 进行优化后,在请求 A 的同时会预加载 C 通过优化 Rollup 产物依赖加载方式节省了不必要的网络开销。
总结
首先,Esbuild 作为构建的性能利器,Vite 利用其 Bundler 的功能进行依赖预构建,用其 Transformer 的能力进行 TS 和 JSX 文件的转译,也用到它的压缩能力进行 JS 和 CSS 代码的压缩。
接着,我给你介绍了 Vite 和 Rollup 的关系。在 Vite 当中,无论是插件机制、还是底层的打包手段,都基于 Rollup 来实现,可以说 Vite 是对于 Rollup 一种场景化的深度扩展,将 Rollup 从传统的 JS 库打包场景扩展至完整 Web 应用打包,然后结合开发阶段 no-bundle 的核心竞争力,打造出了自己独具一格的技术品牌。
因此,你可以看出双引擎对于 Vite 的重要性,如果要深入学习和应用 Vite,那么掌握 Esbuild 和 Rollup 的基础使用和插件开发是非常有必要的。