预构建做了什么?
依赖预构建主要做了两件事情:
-
将其他格式(如 UMD 和 CommonJS)的产物转换为 ESM 格式,使其在浏览器通过
<script type="module"><script>的方式正常加载。 -
打包第三方库的代码,将各个第三方库分散的文件合并到一起,减少 HTTP 请求数量,避免页面加载性能劣化。
这两件事情都是由 Esbuild 基于 Golang 开发,是Vite项目启动速度快的一个重要原因,也不像Webpack/Rollup这些有打包性能问题。
为什么要预构建?
我们先介绍一下不使用预构建的问题
Vite 是基于浏览器原生 ES 模块规范实现的 Dev Server,所以不管是应用代码还是第三方库代码,都需要符合 ESM 规范才可以运行。
但是有很多的第三方库是不符合 ES 规范的,我们也没办法控制第三方库的代码规范,所以我们需要把它们转换成 ESM 格式。
另外还有请求瀑布流的问题,例如有些三方库是符合 ES 规范的,Vite可以直接运行,但是这个库会发出很多的请求,会导致页面卡顿,如下图:
每个import都会触发一次新的文件请求,因此在这种依赖层级深、涉及模块数量多的情况下,会触发成百上千个网络请求,而 Chrome 同一个域名下最多同时支持6个HTTP并发请求,所以会导致页面加载卡顿,但是依赖预构建之后,会把这个三方库打包成一个文件,这样请求数量就变少很多,页面也就流畅的多,如下图:
如何使用预构建?
Vite中有 自动开启 和 手动开启 两种开启模式
一、自动开启
项目启动后可以在 node_modules 里面看到 .vite 目录 ,这里是预构建存放文件的地方,内容如下:
依赖的请求结果会设置缓存,在缓存过期之前,预构建不会在使用 Vite Dev Server 而是直接使用缓存结果。
除了 HTTP 缓存,Vite 还设置了本地文件系统的缓存,所有的预构建产物默认缓存在node_modules/.vite目录中。如果以下 3 个地方都没有改动,Vite 将一直使用缓存文件:
- package.json 的
dependencies字段 - 各种包管理器的 lock 文件
optimizeDeps配置内容
二、手动开启
有些场景下我们不想用本地的缓存文件,比如需要调试某个包的预构建结果,可以使用下面任意一种方法清除缓存,还有手动开启预构建:
- 删除
node_modules/.vite目录。 - 在 Vite 配置文件中,将
server.force设为true。 - 命令行执行
npx vite --force或者npx vite optimize。