前言
Vite对于前端到底需不需要打包提出了自己的观点,在某些情况下他做的确实更好。
打包
首先回顾一下什么是打包,从结果导向来看,打包使得开发人员所写的代码和最终运行的代码是不甚相同的两个样子,这样做有什么好处呢?
- 在HTTP2普及之前,浏览器对于多路复用是没有啥概念的,因此我们可以选择打包成一个bundle,目的是减少大量文件并行请求支持不足的问题。
- 在ES6普及之前,为了兼容性,可能仍然需要编译乘ES5的代码保证run everywhere。
- vue和react这种JS库或者MVVM框架,我们总不能每次都让他在浏览器中编译运行把,因此需要打包成静态文件以便生产环境使用,同理CSS预处理器等也是大概的道理。
既然如此,我们似乎可以看到打包的需要越来越少了,毕竟打包成本还是有的,但是似乎大型应用还是离不开webpack:
- HTTP2的多路复用是可以,但是webpack也不是不能打包成多个bundle,这一点已经不是那么重要。
- ES6对现代浏览器的支持越来越完备。
- MVVM配合webpack,及其周边生态,确实已经非常好用了。
缺点自然也罗列一下:
- 首先就是打包必然是耗时的。
- 其次webpack作为一个异常强大的工具,所包含的东西着实是太多了,因此在对配置玩的不是那么透的情况下,很容易带来额外的负担,典型的表现就是许多官方推出的脚手架的很多东西都是臃肿的。
Vite
那么vite到底是个什么东西呢?简单地说,vite是一个基于浏览器原生 ES imports 的开发服务器,他并不是完全取代webpack的东西,或者说他只是取代了webpack-dev-server,也就是说在开发场景下vite抛弃了打包这个概念,但是在生产环境中vite官方仍然使用rollup进行打包。
原理
首先是es modules的出现,我们可以在script标签上添加module模式:
<script type="module">
import {a} from "./a.js"
</script>
JS引擎对这部分进行解析的时候,首先通过对其内部的import等发起HTTP请求,拿到内容之后在进行解析。
而Vite所做的工作即对这一次请求进行拦截,同时在后端对对应的文件进行处理,举个例子如对Vue模板的解析。
因为这个过程中,我们并没有打包这个步骤,这一定程度上大大优化了开发体验,最明显的就是热更新速度,对于webpack,热更新过程势必伴随着重新打包构建,而对于只编译的vite来说,如果某个js包并没有参与某次热更新的影响,那么他自然也不需要重新编译,在package过多的情况下,这样的做法往往有着很高的收益。
拦截请求
为了看到真正的请求和我们开发环境代码的差异,这里我们用create-vite-app作一个Demo,具体使用方式这里按下不表,demo结构如下:
接着看一下开发环境下的index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module">
import { createApp } from "vue";
import App from "/src/App.vue";
createApp(App).mount("#app");
</script>
</body>
</html>
再看一下编译后的html:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module">import "/vite/client"</script>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module">
import { createApp } from "/@modules/vue.js";
import App from "/src/App.vue";
createApp(App).mount("#app");
</script>
</body>
</html>
我们可以看到明显的差异,毕竟没了webpack帮我们在node-modules中找到相应的包,vite自然要做一层拦截修改,当以@modules/vue.js再次请求时,vite又会拦截到,导向真正的模块。vite官方是使用koa作为服务器后端的。
最后
vite目前还在进一步开发,作为一个优秀的开发服务器,并囊括了不错的打包工具,他不仅仅支持Vue,如今已经完成了React等的支持,推荐你可以试一试。