vite介绍

235 阅读4分钟

分享目的: 了解使用vite,了解其基本运行原理。后续计划引入block体系中。

一、why vite

现实问题

浏览器支持 ES 模块之前,JavaScript 并没有提供的原生机制让开发者以模块化的方式进行开发。因此产生了webpack,rollup等打包工具,

将我们的开发代码打包为在浏览器端能运行的代码。产生的问题是当项目越来越大,本地构建时间通常需要很久。

Vite 旨在利用浏览器开始原生支持 ES 模块解决此问题。

服务器启动缓慢

依赖:vite将使用esbuild将node_modules下的依赖进行打包。(Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。)

源码: vite将jsx,vue等文件直接转化为浏览器能识别的esm形式文件。浏览器自己依据情景导入所需文件

1.png

2.png

更新缓慢

在实践中我们发现,即使采用了 HMR 模式,其热更新速度也会随着应用规模的增长而显著下降

在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失活(大多数时候只是模块本身),使得无论应用大小如何,HMR 始终能保持快速更新。

Vite 同时利用 HTTP 头来加速整个页面的重新加载,304缓存依赖模块。

为什么生产环境仍然需要打包?

尽管原生 ESM 现在得到了广泛支持,但由于嵌套导入会导致额外的网络往返,在生产环境中发布未打包的 ESM 仍然效率低下(即使使用 HTTP/2)。

为了在生产环境中获得最佳的加载性能,最好还是将代码进行 tree-shaking、懒加载和 chunk 分割(以获得更好的缓存)。

由于vite在启动的时候不需要打包,也就意味着不需要分析模块的依赖、不需要编译,因此启动速度非常快。

当浏览器请求某个模块时,再根据需要对模块内容进行编译。这种按需动态编译的方式,极大的缩减了编译时间,项目越复杂、模块越多,vite的优势越明显。

现象就是第一次加载会比较慢,刷新后加载较快

二、功能

依赖预构建

1.预构建 它们可以提高页面加载速度,并将 CommonJS / UMD 转换为 ESM 格式

预构建这一步由 esbuild 执行,这使得 Vite 的冷启动时间比任何基于 JavaScript 的打包器都要快得多。

webpack 本身维护了一套模块系统,这套模块系统兼容了所有前端历史进程下的模块规范,包括 amd commonjs es6 等。

2.将每个文件中所需的依赖项重写,让浏览器能够找到对应依赖。

最终的代码都是交给浏览器执行的。vite更多的是利用了浏览器支持esm特性。

3.依赖是强缓存的,进一步利用了浏览器的特性,加速构建和加载过程。对比没有分包过的webpack,每次刷新页面都需重新加载整个js包。

同时vite会将打包后的文件放入node_modules下的 .vite文件,下次启动时直接使用缓存文件,当然也可以启动的时候加上 --force不使用缓存文件。实际两者差不不大,因为 esbuild 打包真的很快。

3.png

模块热重载

Vite 提供了一套原生 ESM 的 HMR API。 具有 HMR 功能的框架可以利用该 API 提供即时、准确的更新,而无需重新加载页面或清除应用程序状态。

开箱即用

typescript,jsx,vue,css预处理器,静态资源等都是开箱即用,不需要做相关loader等配置。

三、使用过程中碰到的问题

require语法无法支持

源代码中无法支持

4.png

解决方案: 手动将所有require方法重写为import导入

使用插件在vite编译时将require翻译为import

node_modules中无法支持

node_modules中require语法是支持的,但是require('xxx.css')是无法支持的。require is not defined

解决方案:重新打包相应模块,生成es文件,在packagejson中导入module字段配置。

window.require = () => {} 然后再在文件中import相关css文件(不推荐)。

todo:why node_moudles中能够支持require('xxx.js'),但是src中不行。

装饰器语法不支持

必须使用ts文件同时要在vite.config.js中作相关配置。

@vitejs/plugin-react 提供了相关react的插件。

5.png

其他奇奇怪怪问题

vite接入问题记录

后续block/cli中实现的功能,通过vite的createServer实现。lion接入,html插入raptor,埋点。sso等等等