115  
查询码:00000356
vue2 怎么用vite_下一代前端构建工具Vite
来源:https://blog.csdn.net/weixin_42139357/article/details/112331406
作者: 朱凡 于 2022年02月18日 发布在分类 / FM组 / FM_App 下,并于 2022年02月18日 编辑
项目 使用 服务 服务器 开发 浏览 浏览器 文件 更新 博客

vue2 怎么用vite_下一代前端构建工具Vite


一、背景

Vue作者尤雨溪在今年4月提出了一个由Vue3搭载的前端开发工具Vite。Vite主要提供了前端开发服务器的功能以及生产环境打包的功能,而其主要突破则是在前端开发服务器这一方面,提供了一种基于ES Module的快速的本地开发服务器。

二、Vite简介

2.1 什么是Vite

在本文编辑时,Vite版本仍处于1.0.0-rc.9,尚未正式发布,并且Vite目前主要支持Vue3项目,尚不识别Vue2语法。下面是引用尤雨溪在微博上对Vite的介绍。

Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则可以把同一份代码用 rollup 打。虽然现在还比较粗糙,但这个方向我觉得是有潜力的,做得好可以彻底解决改一行代码等半天热更新的问题。

2.1 如何使用Vite

使用下面的命令即可快速搭建一个使用Vite作为开发服务器的项目,使用十分方便,类似于Vue-cli。

$ npm init vite-app $ cd $ npm install $  npm run dev

第一行命令的目的就是从npm仓库拉取create-vite-app这个包,然后全局安装,最后使用它创建基于Vite的模板项目。

三、Vite特性

官方文档介绍,Vite主要有下面三个特性

  1. 快速的冷启动

  2. 及时的热模块更新

  3. 真正的按需加载 我们对比create-vite-app和Vue-cli创建的项目,来看一下Vite快在哪里,下图分别是使用Vite和Vue-cli(webpack)启动本地开发服务器的过程。

3fc388d09e17eee019d7f469a437d2a8.gif

406ded21c1d6bffb0161f69a8ee373e4.gif

可以看出Vite相对于Vue-cli(webpack)在本地服务器启动时省略了打包步骤,因而做到了冷启动秒开的效果,并且这个速度提升会随着项目模块增多而愈加明显。下面我们就看一下Vite是如何实现其快速的特性。

四、Vite原理

Vite 是基于浏览器原生 ES imports 的开发服务器。因而我们首先需要了解浏览器是如何支持ES Module的

4.1 ES Module

首先,我们来看一下在浏览器如何使用ES Module。打开浏览器调试面板, 清空network,使用下面代码在页面动态插入一段 代码

const script = document.createElement('script')script.setAttribute('type', 'module');script.innerHTML = 'import {test} from "./test.js"'document.body.append(script)

d296a209509c4b9f3b9daa3a7c43ea37.png

在运行上述代码后,浏览器向当前服务器目录发送了http://km.oa.com/test.js的请求。我们都知道本地项目中我们使用ES import会从文件系统读取相应路径的模块,浏览器则是将模块路径转换为Url。

657c0b7dfbe5fab080b0d8cef8c11afe.png

浏览器解析ES module的过程如上图所示。

  1. 识别带有熟悉type="module"的标签

  2. 获取并解析该标签内的js内容。

  3. 识别import语法,生成请求url,向服务器请求该地址的模块

可以说浏览器对于ES Module的支持实现了真正的按需加载,省略了前端打包的过程,对于减少首屏加载时间是有极大帮助的。但是我们要在生产环境中使用它必须知道浏览器的支持度到底如何。

下面是一张caniuse中说明的浏览器对于 ES Module的静态import语法的支持情况。可以看出除了IE外的主流浏览器基本上都支持了 ES Module的import语法。

ad57ec6f0d63721fc632fe6449836428.png

那么,对于不支持ES Module的浏览器,难道我们就让项目跑不起来吗?

当然不是,在 script 标签中使用 nomodule 属性,可以确保向后兼容。

f8ece39821a1c2e233e55f1abb8149ba.png

像上图一样提供ES Module方式和非ES Module方式的代码,对于支持ES Module的浏览器,其会忽视nomodule类型的script,而对于无法识别 Es Module的浏览器则会直接使用nomodule的script代码。因此我们只需提供一份打包好的代码,放在nomodule标签内就可以实现向后兼容

值得注意的是,浏览器只能解析以’/’, ‘./’, 或 '…/'开头的模块路径,对于像引用nodemodules中的模块,比如像下面引用Vue的方式,浏览器无法识别,会报错。因此对于nodemodules的引用,需要另外处理,而Vite也给出了解决方案。

import Vue from 'vue'

4.2 Vite开发服务器如何使用ES Module

我们启动Vite本地开发服务器,用浏览器打开入口页面,观察浏览器的NetWork面板.如下图所示,

  1. 浏览器加载了入口html,解析发现main.js,

  2. 发现main.js中包含ES Module, 解析import语法,发现有三个import

  3. 根据import,发出所依赖的模块的Http请求

  4. 依次类推,边解析边请求。

562f7063ecc565dafd88d62393bf787d.png

0cf961963e4bb3b4fc096c7727c1cd94.png

对比源码和网络请求,我们会发现网络请求数明显要多于源码中import的个数。多出的网络请求主要是两类

  1. .vue文件相关 对于一个Vue组件SFC(Single File Components),其主要包含三类代码,模板、script、样式。由于浏览器是无法识别vue文件的,一个vue文件会被拆分为三个请求.vue,.vue?type=template,.vue?type=style,这些都需要借助Vite的本地服务器实现,具体实现方法下文会详细阐述。

  2. 热更新相关 我们看到请求中有个clent.js,还有websocket请求,这些都是为热更新服务的,而在代码中插入建立websocket连接需要的clent.js逻辑也是由Vite开发服务器实现的。

4.3 Vite 开发服务器模块处理

对于浏览器不识别的node_module引用如何处理?对于.vue文件如何处理都是由Vite开发服务器实现的。首先我们看一下Vite开发服务器架构图

c6a560566b8a525d1f638eb4b72c5fe6.png

Vite开发服务器是基于Koa框架的,利用Koa中间件实现模块解析以及热更新的主要功能。这一节我们主要看一下Vite是如何处理模块的。

nodemodules 模块处理过程 对nodemodules的处理主要由中间件serverPluginModuleRewrite完成,其主要过程如下

  1. 在 koa 中间件里获取请求 body

  2. 通过 es-module-lexer 解析资源 ast 拿到 import 的内容

  3. 判断 import 的资源是否是绝对路径,绝对视为 npm 模块

  4. 返回处理后的资源路径:“vue” => “/@modules/vue”

vue文件处理过程 对vue组件的处理由serverPluginVue来实现,其处理流程如下

  1. 分析请求路径,是否包含查询字段type

  2. 不包含type的请求视为script内容请求, 返回类型为js

  3. 对于type为template请求则返回.vue文件的template内容的渲染函数,返回类型为js

  4. 对于type为style的请求则返回.vue文件中style标签内样式的动态插入函数

4.4 Vite 热更新

158e06cb49cb6d7a35a732702c76df62.png

如上图所示,Vite热更新也是基于Websocket。在Vite服务器启动时,Vite利用中间件serverPluginHtml在html中插入client.js. 这个js文件主要用于在建立浏览器和Vite服务器之间的Websocket通信。热更新的步骤如下

  1. Vite服务器监听本地文件更新

  2. 对比缓存中的文件和变动后的文件,组织更新内容

  3. 服务器通过PostMessage向浏览器通知更新消息,更新消息包含跟新类型,更新后模块的最新地址,时间戳

  4. 浏览器请求热更新文件

  5. 根据跟新类型处理返回的文件

clientjs监听的更新消息类型

  • connected: WebSocket 连接成功

  • vue-reload: Vue 组件重新加载(当你修改了 script 里的内容时)

  • vue-rerender: Vue 组件重新渲染(当你修改了 template 里的内容时)

  • style-update: 样式更新

  • style-remove: 样式移除

  • js-update: js 文件更新

  • full-reload: fallback 机制,网页重刷新

总结

Vite 提供了一个更快的开发环境服务器, 其实现原理基于ES模块,通过开发环境去打包将构建时间从 O(n) 减少到 O(1), 其搭载Vue3发布,借助Vue生态,在未来有更广泛的使用场景。




 推荐知识

 历史版本

修改日期 修改人 备注
2022-02-18 23:46:03[当前版本] 朱凡 创建版本

 附件

附件类型

GIFGIF PNGPNG

知识分享平台 -V 4.8.7 -wcp