欢迎访问我的个人博客:https://www.gaoyuan.ink,一起共勉学习~
作为刚刚开始学习vue3,接触到了vite这个名词。还是在vue2和vue3的迁移构建版本中看到了这个词,当时看到Vue 2 应用升级为 Vue 3 (存在限制)中看到Vue 3 不再提供一个包渲染器,且推荐使用 Vite。于是我就去查了一下vite,做了一个通俗易懂的总结。
举个例子,你请我去饭店吃饭,点了10个菜
webpack饭店:后厨全部做完了,一波端一桌子菜,你得多等很久
vite:做好一个就给你上一个你先吃 快不少
有人说:可如果我为了学这个,去了解webpack等等一系列的其他构建工具,岂不是南辕北辙了吗?
这个想法我是反对的,因为这就和你还不会走路就想要飞了是没区别的,个人觉得还是得要去了解,因为了解并不会花费你很多时间,你并不需要去多深入。
前端是一个发展快速的行业,也许很多人觉得它的门槛很低,也有很多标榜了几个月能速成的课程,但是那样是没有灵魂的,只能是生硬的记忆。很多时候你确实需要去了解历史,学习语言就和学习"语言"(中文、英文)是一样的,有一些专有名词(文化)需要了解。
再回到你这个问题,打开 Vite 的官网,他的标语是 「 下一代前端开发与构建工具」,因为一般标语需要言简意赅地表达出它的意思,所以会用最精简的去概括(也是为了宣传)。
而这句话到底要表达出什么意思呢?如果用通俗的话讲就是:
目前大部分浏览器已经支持了EMS(ES Modules)模块的方式了,因此我写了一个转化工具,可以让一些浏览器不支持的格式(.vue/.svelte/.ts)以及不支持的语法(最新的es语法/特性)让浏览器支持,它将会成为趋势。
所以本质 Vite 其实就是利用了浏览器模块化功能的一个代理转化器,转化器应该能明白吧,就是上面说的类似 .vue 转化成 .js 文件。
而以上概念确实利用 webpack 能够让你更加清楚,webpack 官网的例子已经很形象了。就把有相互依赖关系的模块,聚合转化成单个 .js 文件、单个 .css文件以及其他的一些静态文件。
可以看到由于之前的浏览器没有讲模块化的方式统一, 因此是利用了自己的模块化方式,将资源都打包成一个JS,而 Vite 做的就是去除了自己定义一套模块化方式,改用了浏览器默认支持的 ESM, 就将聚合这一部分在实现中去除了,只剩下了转化。
虽然浏览器解决了模块化的依赖,但是依旧是有两个问题:
- 但是没办法支持一些样式/文件资源的 import 语法
- 无法支持.ts/.vue/.svelte 等模板语法(或者高级特性)的直接引用
因此 Vite 为了能够兼容这些语法花了大力气去做这些转化工作,将所有的资源都转化成浏览器可识别的 js 的方式去导入,将 css 文件经过包装,转化为一个 js 文件等等。
剩余的就是他会去通过依赖去生成调用关系,去生成缓存,然后还要将第三方包导成 ESM 的方式,然后还有热更新功能。并且为了能够在生产环境打包,使用了 Rollup ,不仅提供了 ESM 的打包方式,以及你需要的其他模块化方式。
核心是简单的,但是相关的生态想要好用,却是要花大量的精力。
最后再补充点历史:
模块化的发展主要经历了这样几个阶段,「iife、CommonJS、AMD、CMD、UMD、ES Module」 这么几个阶段。(因为 iife 的形式其实也是在一定程度上隔绝了变量的问题,因此也纳入了这个过程中。)
对应的打包关系就是这样:
「iife」(不打包)-> 「CommonJS、AMD、CMD、UMD」(打包)-> 「ES Module」(不打包)
其实究其原因打包不打包的核心问题就是,规范 + 浏览器的推进。
把时间回退到2006年,这个时候 「jQuery」 刚呱呱落地,那个时候虽然没有模块化,使用 jQuery 相比传统那样写已经提高极大的速度,当然虽然已经很方便了,单还是阻挡不了爱研究的程序员们。
在2009年的时候 「CommonJS」 诞生了,但是 「CommonJS」 由于有两个重要问题没能得到解决,所以迟迟不能推广到浏览器上。(1.由于外层没有 function 包裹,被导出的变量会暴露在全局中。2.在服务端 require 一个模块,只会有磁盘 I/O,所以同步加载机制没什么问题;但如果是浏览器加载,一是会产生开销更大的网络 I/O,二是天然异步,就会产生时序上的错误。)中间百家争鸣(「AMD、CMD、UMD」)一直到2016年5月,经过了两年的讨论,ECMAScript 6.0 终于正式通过决议,成为了国际标准。在这一标准中,首次引入了 import 和 export 两个 JavaScript 关键字,并提供了被称为 「ES Module」 的模块化方案。在 JavaScript 出生的第 21 个年头里,JavaScript 终于迎来了属于自己的模块化方案。而在这期间想要使用模块化,只能通过打包工具来解决。
有了标准之后,也不是能立马让所有设备都支持 「ES Module」 因为浏览器的推进是一个漫长的过程,不像服务端,如果做一个升级,只需要对服务端升级,而浏览器的升级伴随着电脑/手机等一系列的因素,因素非常不可控,因为用户总是可以有多种多样的选择,「ES Modules(ESM)」 是 JavaScript 官方的标准化模块系统,而它这一走,却在标准化的道路上已经花费了近 10 年的时间。在2018 年 5 月 Firefox 60 发布之后,所有的主流浏览器就都支持 「ESM」 了。直到现在,「ES Module」 还并不能真正地用在生产环境使用,还是需要转化成以旧的方式。