Vue做者尤雨溪在今年4月提出了一个由Vue3搭载的前端开发工具Vite。Vite主要提供了前端开发服务器的功能以及生产环境打包的功能,而其主要突破则是在前端开发服务器这一方面,提供了一种基于ES Module的快速的本地开发服务器。html
在本文编辑时,Vite版本仍处于1.0.0-rc.9,还没有正式发布,而且Vite目前主要支持Vue3项目,尚不识别Vue2语法。下面是引用尤雨溪在微博上对Vite的介绍。前端
Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,彻底跳过了打包这个概念,服务器随起随用。同时不只有 Vue 文件支持,还搞定了热更新,并且热更新的速度不会随着模块增多而变慢。针对生产环境则能够把同一份代码用 rollup 打。虽然如今还比较粗糙,但这个方向我以为是有潜力的,作得好能够完全解决改一行代码等半天热更新的问题。vue
使用下面的命令便可快速搭建一个使用Vite做为开发服务器的项目,使用十分方便,相似于Vue-cli。node
npm init vite-app <project-name>
cd <project-name>
npm install
npm run dev
复制代码
第一行命令的目的就是从npm仓库拉取 create-vite-app
这个包,而后全局安装,最后使用它建立基于Vite的模板项目。webpack
官方文档介绍,Vite主要有下面三个特性web
create-vite-app
和 Vue-cli
建立的项目,来看一下Vite快在哪里,下图分别是使用Vite和 Vue-cli(webpack)
启动本地开发服务器的过程。能够看出Vite相对于Vue-cli(webpack)在本地服务器启动时省略了打包步骤,于是作到了冷启动秒开的效果,而且这个速度提高会随着项目模块增多而越发明显。下面咱们就看一下Vite是如何实现其快速的特性。npm
Vite 是基于浏览器原生 ES imports 的开发服务器。于是咱们首先须要了解浏览器是如何支持ES Module的浏览器
首先,咱们来看一下在浏览器如何使用ES Module。打开浏览器调试面板, 清空network,使用下面代码在页面动态插入一段 <script>
代码缓存
const script = document.createElement('script')
script.setAttribute('type', 'module');
script.innerHTML = 'import {test} from "./test.js"'
document.body.append(script)
复制代码
在运行上述代码后,浏览器向当前服务器目录发送了 http://km.oa.com/test.js
的请求。咱们都知道本地项目中咱们使用ES import会从文件系统读取相应路径的模块,浏览器则是将模块路径转换为Url。服务器
浏览器解析ES module的过程如上图所示。
type="module"
的 <script>标签
import
语法,生成请求url,向服务器请求该地址的模块能够说浏览器对于ES Module的支持实现了真正的按需加载,省略了前端打包的过程,对于减小首屏加载时间是有极大帮助的。可是咱们要在生产环境中使用它必须知道浏览器的支持度到底如何。
下面是一张caniuse中说明的浏览器对于 ES Module的静态import语法的支持状况。能够看出除了IE外的主流浏览器基本上都支持了 ES Module的import语法。
那么,对于不支持ES Module的浏览器,难道咱们就让项目跑不起来吗?
固然不是,在 script 标签中使用 nomodule 属性,能够确保向后兼容。
像上图同样提供ES Module方式和非ES Module方式的代码,对于支持ES Module的浏览器,其会忽视 nomodule
类型的script,而对于没法识别 Es Module的浏览器则会直接使用 nomodule
的script代码。所以咱们只需提供一份打包好的代码,放在 nomodule
标签内就能够实现向后兼容
值得注意的是,浏览器只能解析以’/’, ‘./’, 或 '…/'开头的模块路径,对于像引用nodemodules中的模块,好比像下面引用Vue的方式,浏览器没法识别,会报错。所以对于nodemodules的引用,须要另外处理,而Vite也给出了解决方案。
import Vue from 'vue'
复制代码
咱们启动Vite本地开发服务器,用浏览器打开入口页面,观察浏览器的NetWork面板.以下图所示,
main.js
,main.js
中包含ES Module, 解析 import
语法,发现有三个 import
import
,发出所依赖的模块的Http请求对比源码和网络请求,咱们会发现网络请求数明显要多于源码中 import
的个数。多出的网络请求主要是两类
.vue
文件相关 对于一个Vue组件SFC(Single File Components),其主要包含三类代码,模板、script、样式。因为浏览器是没法识别vue文件的,一个vue文件会被拆分为三个请求 .vue
, .vue?type=template
, .vue?type=style
,这些都须要借助Vite的本地服务器实现,具体实现方法下文会详细阐述。clent.js
,还有websocket请求,这些都是为热更新服务的,而在代码中插入创建websocket链接须要的 clent.js
逻辑也是由Vite开发服务器实现的。对于浏览器不识别的node_module引用如何处理?对于 .vue
文件如何处理都是由Vite开发服务器实现的。首先咱们看一下Vite开发服务器架构图
Vite开发服务器是基于Koa框架的,利用Koa中间件实现模块解析以及热更新的主要功能。这一节咱们主要看一下Vite是如何处理模块的。
nodemodules 模块处理过程 对nodemodules的处理主要由中间件
serverPluginModuleRewrite
完成,其主要过程以下
vue文件处理过程 对vue组件的处理由
serverPluginVue
来实现,其处理流程以下
js
template
内容的渲染函数,返回类型为 js
style
标签内样式的动态插入函数如上图所示,Vite热更新也是基于Websocket。在Vite服务器启动时,Vite利用中间件 serverPluginHtml
在html中插入 client.js
. 这个js文件主要用于在创建浏览器和Vite服务器之间的Websocket通讯。热更新的步骤以下
clientjs监听的更新消息类型
Vite 提供了一个更快的开发环境服务器, 其实现原理基于ES模块,经过开发环境去打包将构建时间从 O(n) 减小到 O(1), 其搭载Vue3发布,借助Vue生态,在将来有更普遍的使用场景。
原做者:李璐
未经赞成,禁止转载!