Vite 预构建

125 阅读2分钟

预构建做了什么?

依赖预构建主要做了两件事情:

  1. 将其他格式(如 UMD 和 CommonJS)的产物转换为 ESM 格式,使其在浏览器通过 <script type="module"><script>的方式正常加载。

  2. 打包第三方库的代码,将各个第三方库分散的文件合并到一起,减少 HTTP 请求数量,避免页面加载性能劣化。

这两件事情都是由 Esbuild 基于 Golang 开发,是Vite项目启动速度快的一个重要原因,也不像Webpack/Rollup这些有打包性能问题。

为什么要预构建?

我们先介绍一下不使用预构建的问题

Vite 是基于浏览器原生 ES 模块规范实现的 Dev Server,所以不管是应用代码还是第三方库代码,都需要符合 ESM 规范才可以运行。

但是有很多的第三方库是不符合 ES 规范的,我们也没办法控制第三方库的代码规范,所以我们需要把它们转换成 ESM 格式。

另外还有请求瀑布流的问题,例如有些三方库是符合 ES 规范的,Vite可以直接运行,但是这个库会发出很多的请求,会导致页面卡顿,如下图:

image.png

每个import都会触发一次新的文件请求,因此在这种依赖层级深涉及模块数量多的情况下,会触发成百上千个网络请求,而 Chrome 同一个域名下最多同时支持6个HTTP并发请求,所以会导致页面加载卡顿,但是依赖预构建之后,会把这个三方库打包成一个文件,这样请求数量就变少很多,页面也就流畅的多,如下图:

image.png

如何使用预构建?

Vite中有 自动开启手动开启 两种开启模式

一、自动开启

项目启动后可以在 node_modules 里面看到 .vite 目录 ,这里是预构建存放文件的地方,内容如下:

image.png

依赖的请求结果会设置缓存,在缓存过期之前,预构建不会在使用 Vite Dev Server 而是直接使用缓存结果。

除了 HTTP 缓存,Vite 还设置了本地文件系统的缓存,所有的预构建产物默认缓存在node_modules/.vite目录中。如果以下 3 个地方都没有改动,Vite 将一直使用缓存文件:

  1. package.json 的 dependencies 字段
  2. 各种包管理器的 lock 文件
  3. optimizeDeps 配置内容

二、手动开启

有些场景下我们不想用本地的缓存文件,比如需要调试某个包的预构建结果,可以使用下面任意一种方法清除缓存,还有手动开启预构建:

  1. 删除node_modules/.vite目录。
  2. 在 Vite 配置文件中,将server.force设为true
  3. 命令行执行npx vite --force或者npx vite optimize