Vite
一、机制
1.1 Vite 原理?
开发环境: Vite
利用浏览器去解析 imports
,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用(就相当于把我们在开发的文件转换成 ESM 格式直接发送给浏览器)。 当浏览器解析 import HelloWorld from './components/HelloWorld.vue'
时,会向当前域名发送一个请求获取对应的资源(ESM支持解析相对路径),浏览器直接下载对应的文件然后解析成模块记录(打开 network 面板可以看到响应数据都是 ESM 类型的 js)。然后实例化为模块分配内存,按照导入导出语句建立模块和内存的映射关系。最后运行代码。vite
会启动一个 koa
服务器拦截浏览器对 ESM
的请求,通过请求路径找到目录下对应的文件并处理成 ESM
格式返回给客户端。vite
的热加载 是在客户端和服务端之间建立了 websocket 连接,代码修改后服务端发送消息通知客户端去请求修改模块的代码,完成热更新,就是改了哪个 view
文件就重新请求那个文件,这样保证了热更新速度不受项目大小影响。开发环境会使用 EsBuild
对依赖进行个预构建缓存,第一次启动会慢一点,后面的启动会直接读取缓存
生产环境: 使用 rollup
来构建代码,提供指令可以用来优化构建过程。缺点就是开发环境和生产环境可能不一致;
1.2 Vite 生产环境为什么使用 RollUp?
1. 为什么生产环境仍然需要打包?
答: 尽管原生 ESM
现在得到了广泛支持,但由于嵌套导入会导致额外的网络往返,在生产环境中发布未打包的 ESM
仍然效率低下(即使使用 HTTP/2
)。为了在生产环境中获得最佳的加载性能,最好还是将代码进行 tree-shaking
、懒加载和 chunk
分割(以获得更好的缓存)。
2. 为什么使用 RollUp
作为打包工具?
答: Vite
是一个由原生ESM
驱动的Web
开发构建工具。在选择构建工具的时候也最好可以选择基于ESM
的工具。
-
虽然
EsBuild
快得惊人,并且已经是一个在构建库方面比较出色的工具,但一些针对构建 应用 的重要功能仍然还在持续开发中 —— 特别是代码分割和CSS
处理方面。 -
Rollup
是基于ES2015
的JavaScript
打包工具,Rollup
在应用打包方面更加成熟和灵活。它将小文件打包成一个大文件或者更复杂的库和应用,打包既可用于浏览器和Node.js
使用。Rollup
最显著的地方就是能让打包文件体积很小。相比其他JavaScript
打包工具,Rollup
总能打出更小,更快的包。因为Rollup
基于ES2015
模块,比Webpack
和Browserify
使用的CommonJS
模块机制更高效。
1.3 Vite 为什么基于 EsBuild 预构建依赖?
1. 为什么需要预构建?
答: 原因如下:
-
支持
commonJS
依赖:Vite
是基于浏览器原生支持ESM的能力实现的,但要求用户的代码模块必须是ESM
模块,因此必须将commonJs
的文件提前处理,转化成ESM
模块并缓存入node_modules/.vite
-
减少模块和请求数量:
Vite
将有许多内部模块的ESM
依赖关系转换为单个模块,以提高后续页面加载性能。比如说lodash
工具库,里面有很多包通过单独的文件相互导入, 当代码中出现import { debounce } from 'lodash-es'
会发出几百个HTTP
请求, 这些请求会造成网络堵塞,影响页面的加载。通过预构建lodash-es
成为一个模块,也就只需要一个HTTP
请求了!
2. 为什么用 EsBuild
来预构建
答: EsBuild
为新一代的打包工具,提供了与 Webpack
、Rollup
、Parcel
等工具类似的打包能力, 但是在打包速度上比这三个快了将近 10-100
倍。
-
EsBuild
使用Go
语言编写, 该语言可以编译为原生代码,在编译的时候将语言转化为机器语言,在启动的时候直接执行即可,在CPU
密集的场景下,GO
语言更有优势 -
Go
语言天生具有多线程的优势 -
EsBuild
对构建流程进行了优化,充分利用了CPU
资源。