是什么

  1. vite开发环境利用浏览器的import机制 ES module
  2. 打包内置的rollup,所以已经可以直接用了

简单讲 vite 开发阶段基于es module机制 生产借助rollup (webpack也行的) 两套方式

vite是什么 - 图1

实现按需打包

webpack 之类的打包工具会将各模块提前打包进 bundle 里,但打包的过程是静态的——不管某个模块的代码是否执行到,这个模块都要打包到 bundle 里,这样的坏处就是随着项目越来越大打包后的 bundle 也越来越大。
开发者为了减少 bundle 大小,会使用动态引入 import() 的方式异步的加载模块( 被引入模块依然需要提前打包),又或者使用 tree shaking 等方式尽力的去掉未引用的模块,然而这些方式都不如 vite 的优雅,vite 可以只在需要某个模块的时候动态(借助 import() )的引入它,而不需要提前打包,虽然只能用在开发环境,不过这就够了

因为使用的是ES module import 所以本身就是我执行到这个api就触发请求 加载进来 天然支持动态加载

vite 如何处理 ESM

既然 vite 使用 ESM 在浏览器里使用模块,那么这一步究竟是怎么做的?
上文提到过,在浏览器里使用 ES module 是使用 http 请求拿到模块,所以 vite 必须提供一个 web server 去代理这些模块,上文中提到的 koa 就是负责这个事情,vite 通过对请求路径的劫持获取资源的内容返回给浏览器,不过 vite 对于模块导入做了特殊处理

综述

Vite (法语寓意“快”,发音 /vit/ )是一个明显提升前端开发体验的新一代前端开发构建工具,它主要包括两个部分:

  • 一个运行使用 原生 ES 模块 的源文件的开发服务器,有 丰富的嵌入特性 和极快的 热模块替换(HMR)
  • 一个使用 Rollup 打包代码的构建命令,通过配置即可输出极优的用于开发环境的静态资源

除此之外,Vite 通过其 插件API 和 Javascript API 具有极强的可扩充性[1]。

为什么使用原生 ES 模块

现在大多数 js 开发者都熟悉下面的 ES 模块语句:

  1. import { foo } from './other-module'

这个语句早已得到 主流浏览器的普遍原生支持,然而,在浏览器原生支持 ES 模块之前,我们不得不依赖于打包工具(Browserify, webpack, Parcel or Rollup)将模块代码组合成单文件使其能在浏览器上运行,即使开发时也是这样。
开发环境中打包有两个缺点:

  • 服务启动慢:启动开发服务器时,打包工具总是遍历整个应用,即使你的项目中用到了代码分隔技术。例如,一个应用有12个懒加载的路由,但你必须要等打包工具处理完程序中的每一个文件,才能开始运行一个单路由页面。

image.png
Vite 怎么解决:服务器启动前不需要准备工作—— Vite 只在浏览器发来请求时,按需编译和执行请求的文件,如果使用了代码分隔技术,只有当前路由使用的模块才会被运行。
image.png

  • 更新慢:当一个文件被修改后,除了重新编译当前文件,打包工具还要验证与其相关的模块部分并重新打整个包,这意味着当你的应用越来越大时,保存文件后浏览器界面更新的反馈速度会急剧线性增长。在大型应用中,这种打包重建步骤所付出的代价是及其昂过的,即使启动了热更新替换

Vite 怎么解决: 每个运行的文件都通过HTTP报文头(304 Not Modified )来缓存,如果浏览器的缓存机制被禁用,就通过Vite的内存缓存机制,文件被编辑后,只需要验证缓存中的相应文件。另外,基于原生 ES 模块的热模块替换只需要精确请求未经过验证的模块,这使得它无论在多大的应用中都很快。

为什么生产环境要打包?

尽管原生 ES 模块已被广泛支持,但将未打包的 ES 模块直接放到生产环境的效率不高(即使用 HTTP/2),因为重复导入会导致额外的来回调用的网络请求。为了最佳的加载体验,生产环境最好还是使用 tree-shaking 、懒加载和包分隔(为了更好的缓存)来打包代码。
确保开发环境和生产环境的最佳输出和两者表现一致并不容易,这也是为什么 Vite 有一个开箱即用的预配置式打包命令。

浏览器支持

尤大说:

vite 启动快就是不需要提前编译,而是当打开浏览器的时候,请求到达服务器的时候才会去编译对应模块。发送到服务器的代码保留着 ES import 的语法,浏览器看到这些 import 就会继续向服务器请求文件,相当于是让浏览器去处理import的关系,服务器会编译完了会返回给浏览器。这样的好处就是当前页面引用多少模块就编译多少,在大型项目中就特别有优势,大型项目可能有很多的路由,如果用webpack 的话那就需要将所有的组件都编译完成才能跑起来这个当前路由。发布的时候 用 rollup打包编译。

webpack 是把所有的模块都提前编译打包到内存里,vite只编译我当前这个页面对应的组件。

尤大自己也说,很难一句话描述清楚 Vite 到底是什么。主要原因可能是它主要包括两个部分,一个基于 ESM[14] 的利用 esbuild[15] 的开发服务器,另一个部分是基于 Rollup[16] 的配置化的打包器。当然还有很多其他强大的功能,但是已经超过一句话了。尤大说市面上最接近 Vite 的产品是 Parcel[17],但二者的实现原理完全不同。

本质原因应该是大部分现代浏览器(除了 IE 11)已经对原生 ES 模块支持的很好了,而且新版的 Node 也支持 ESM 了。ESM 终于可以在不久的将来一统江湖。原生的就是香。

Esbuild 是 Vite 为何如此快速的原因,它比传统 tsc 快 20-30 倍。Vite 用 esbuild 替代 Rollup 进行预打包,速度也非常快。这里尤大透露了他的工作电脑,搭载 M1 芯片的 ARM 架构的 Mac Book Pro,遗憾的是,当时的 esbuild 还不支持 ARM 架构,但 Go 的最新版已经支持。没想到过了几天,esbuild 就发布了其支持 M1 芯片的版本,尤大在第一时间做了测试:

为啥生产模式不用 esbuild,不是更快吗?

尤大说:其实也想用,但是 esbuild 目前对生产包支持不够健壮,很多配置无法通过 esbuild 实现。所以目前而言,Rollup 是一个好选择,虽然远比 esbuild 慢。另外,可以用 esbuild 作为压缩器,替代 terser,详见 build.minify[40],这样会更快,但是包的体积可能会有 5% - 10% 左右的增长,看用户取舍。

https://blog.csdn.net/qq_34998786/article/details/115543211?spm=1001.2014.3001.5501

https://juejin.cn/post/6937847568114122760

https://blog.csdn.net/qq_34998786/article/details/115107464?spm=1001.2014.3001.5501