Description
简介
Vite 是新一代的前端构建工具,它的同类产品有 Webpack,Rollup 和 Parcel 等,第一个版本于 2020 年 11 月发布。对于构建工具来说,基本功能就是作为开发服务器,利于开发调试,提高效率;另外就是构建打包我们的前端应用,方便部署。那么 Vite 在这些功能上与其它的构建工具有什么区别呢?
核心思想
在前端技术飞速发展的今天,我们大多采用的是单页面的模式开发应用,这种模式是指在主目录下有个 index.html 文件,里面我们放置一个容器,例如 <div id="app"></div>
。接着当页面渲染时,我们采取客户端渲染的方式,把 JS 逻辑在浏览器上跑一遍,最终通过各种路由匹配,呈现出页面。通常我们不会自己写 DOM 相关的逻辑,而是借助 React、Vue 这样的框架帮我们搞定,我们只需要描述页面结构并且写好处理逻辑就行了。
那这跟构建工具有什么关系呢?关系在于,我们开发的项目里有许多 JS 业务逻辑,而且散落着各种各样的资源文件,例如图片、js 文件、css 文件等等。我们需要有一个“帮手”可以帮助我们更好地管理资源文件,而且附带一些“功能”可以提高我们的开发效率,于是 Webpack、Rollup 这些工具应运而生了。那这些工具都是怎么做的呢?
以 Webpack 为例,它的思想是: 先抓取你项目中的所有文件,递归式地获取,生成模块的依赖关系图,然后依次处理每一个依赖,有些依赖比如 JS 文件 Webpack 自己能识别处理;有些文件比如 CSS、Excel 之类的,Webpack 处理不了,会交给一个叫 loader 的东西去加载处理。最终处理的结果就是,项目中所有的文件都模块化的导入到了一个 bundle 文件,这个文件最终交给浏览器请求执行。所以如果不这么做的话,比如你项目里有几个 js 文件,几十张图片,几个 css 文件,那可能到浏览器里要发起好几次 http 请求,而 Webpack 这些工具预先处理好我们的项目文件,然后只需要一个 bundle 文件请求执行就可以。
图片来源于 Vite 官网
Webpack 已经能很好地帮助我们开发了,那为什么还出现 Vite 呢?这一定是 Webpack 在某些方面有些“问题”。首先是启动,Webpack 每次启动开发服务器,都需要抓取你整个项目,然后递归分析整个项目依赖,最后打包生成 bundle 文件,这个启动过程太耗时了;再来看更新,服务启动后,假如你修改了某个文件,Webpack 需要重新打包生成新的 bundle 文件,这个重新构建的过程同样耗时。虽说后面出现了 HMR 热更新,可以定位到局部的变动模块,然后快速更新,但随着应用规模的膨胀,构建也需要好几秒才能反应到浏览器里。
针对 Webpack 的这些问题,Vite 出现了。它着力于改善项目构建开发体验,提高开发效率。首先,Vite 在启动时会对项目依赖进行分析,将文件分成依赖和源码两类,并使用 esbuild 预构建依赖。源码则是在浏览器请求时,Vite 会拦截并进行按需转换,然后返回给浏览器。这两步说明,Vite 在启动时,并不需要做打包整个模块等昂贵操作,因此启动很快。
图片来源于 Vite 官网:
再来更新,Vite 也采用 HMR 热更新,并且是在原生 ESM 上执行。当文件变动时,Vite 快速定位到变动文件,使其与最近的 HRM 边界之间的链失活,然后更新它。除此之外,Vite 借助浏览器缓存,对依赖模块进行强缓存,对源码模块进行协商缓存,免去了重复请求,提升了性能。
Vite 能够做到上述这些,还是因为现在浏览器开始原生支持 ESM,并且借助强大的 esbuild —— 它是使用编译型语言 Go 写的,比其它使用解释型语言写的快 10-100 倍。值得注意的是,由于插件 API 兼容问题,Vite 在生产环境打包并没有采用 esbuild,而是使用了 Rollup ,配合一套构建优化命令,可以生成比较 tree-shaking 的打包产物。