持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情
- Hello,这里是mouche,当然你也可以叫我某车,反正大家都爱这么叫😁
一、依赖预购建
- 我们应该都知道
Vite基于浏览器的ESM的支持实现了no-bundle的服务 - 这个
no-bundle的服务也仅限于开发过程中针对项目源代码,对于第三方依赖而言,Vite还是选择了对其进行打包(bundle) - Esbuild提供了打包API:esbuild -build- API
- 根据指定的单个或者多个入口,分析依赖,并使用
loader将不同格式的内容转化为 js 内容,生成一个或多个bundle文件
原因
- 第三方依赖不是全部都支持
ESM(毕竟是后面才出现的), 但是CommonJS和UMD相关代码无法在Vite直接运行,因为Vite的开发服务器将所有代码默认为原生ESM,那么就需要有东西来将它做一个转换 - 每有一个
import就会发起一个HTTP请求,在依赖层级比较深,依赖模块比较多的时候,无疑会触发大量的HTTP请求产生,而我们的浏览器比如说Chrome对于同域名的请求,一次只允许并发6个,所以处理大量的请求无疑会慢慢慢。。。,那么就需要有个东西来对他进行一个打包
操作
主要就是针对上述的原因进行操作
- 将其他格式(如
UMD和CommonJS)的产物转换为ESM格式,使其在浏览器能够基于<script type="module"><script>的方式正常加载代码 - 是打包第三方依赖的代码,将各个第三方依赖代码分散的文件合并到一起,减少 HTTP 请求数量,避免页面加载性能劣化
Vite 1.x使用Rollup来做这件事,但是Vite2.x采用ESbuild来完成第三方依赖的预构建,原因呢,就是它真的快
作为打包工具的缺陷
- 不支持降级到
ES5的代码,这就是说在低端的浏览器代码可能会跑不起来 - 不支持
const enum的语法,如果使用这些语法则会报错 - 核心代码是用
golang编写,用户使用的直接是编译出来的binary代码和一堆js的胶水代码,binary代码几乎没法断点调试 - 不支持自定义代码分割(
Code Splitting)策略,降低了拆包优化的灵活性 - 相比于
webpack和rollup庞大的plugin插件支持,ESbuild目前还是比较少的
所以目前
vite还是采用在生产环境还是采用Rollup, 不过官网也表示了当未来这些功能稳定后,也不排除使用esbuild作为生产构建器的可能
二、作为转译工具
Esbuild提供转译API:esbuild -transform API- 通过这个 api,我们可以将
ts、jsx、tsx等格式的内容转化为js。transfrom只负责文件内容转换,并不会生成一个新的文件
支持ts
Vite天然支持引入.ts文件- 在
TS(X)/JS(X)单文件的编译上,Vite使用Esbuild进行了语法转译 - 原因也是因为它快,
Vite使用Esbuild将TypeScript转译到JavaScript的速度,约是tsc速度的20-30倍,同时HMR更新反映到浏览器的时间小于50ms - ESbuild转译的能力是通过Vite插件插件实现的,这个插件在开发和生成环境都会执行,所以它也用于生产环境中
局限
Vite仅执行文件的转译工作,并 不执行 任何类型检查。并假设类型检查已经被你的IDE或构建过程接管了- 所以使用
Vite搭建vue项目的话,在打包的时候,一般会先给他做一下类型检查
三、压缩
- 在生产环境中
Esbuild压缩器通过插件的形式融入到了Rollup的打包流程中 - 我们在前面提过,
Esbuild是基于Golang编写的, 传统的方式Terser是使用JS开发的; 对于压缩这种CPU密集型的工作,性能比不上Golang这种原生语言 - 同时,
ESbuild是共享AST的,而Terser在AST操作的时候,在各个工具中是无法共享的 - 所以使用它的原因也可以是 “快”