最近闲下来后开始整理之前的知识了,早在vue3.0正式出来之前,尤大就已经提到了做了一个新的web应用开发工具vite

解下来的几篇文章我会对vite的使用,到与webpack(其实应该是webpack-dev-server,后面会解释为什么)的比较,以及源码解析,简单地实现vite部分功能来写,欢迎大家在评论区提出各种建议问题

那么话不多说,开始vite学习之路

vite是什么

首先,vite为什么叫做vite,vite实际上是法语中快的意思,所以顾名思义,这个工具给我们带来的就是更快的开发体验,它实际上是一个面向现代浏览器,基于ECMA标准的ES module实现的一个更轻更快web应用开发工具

之所以是面向现代浏览器,而不顾之前的浏览器,是因为vite本身是一个web应用开发者工具,而对于开发者来说,一般都是使用比较先进的浏览器来进行开发,所以我们可以直接使用一些现代浏览器支持的特性,而不考虑去兼容一些老的浏览器

而现代浏览器支持的特性中,在vite中最为重要的一个,就是ES module。由于vite是面向现代浏览器的,所以它利用浏览器去解析imports,在服务器端按需编译返回,跳过打包过程。同时支持Vue文件和HMR(热更新),针对生产环境可以使用rollup打包。

此外要注意的一点是,vite仅支持vue3.0+的项目,也即是说我们无法在其中使用vue2.x

vite的使用

说完vite是什么只会,接下里开始尝鲜

vite项目是基于create-vite-app脚手架搭建的,这里我们直接使用npm init命令(cliName是脚手架名,projectName是项目名)

npm init <cliName> <projectName>

npm init命令在执行时,如果对应<cliName>的脚手架没有安装的话,就会自动安装对应的脚手架工具

npm i create-<cliName>

所以这里直接执行

npm init vite-app <projectName>

就会安装对应的create-vite-app
所以完整的命令执行下来是

npm init vite-app <projectName>
cd <projectName>
npm i 
npm run dev

打开对应地址就能看到一个vue项目被启动了
在这里插入图片描述
然后可以查看文件目录
在这里插入图片描述
其实和我们平时的vue项目差不多,而可以注意到的一点是,vite将index.html放到了文件的根目录,而实际上,在vite服务器启动后,该服务器下访问的根目录,就是该项目的根目录

比如我们访问
localhost:3000/package.json
(这里不一定是3000,要看启动服务器时的端口号)
在这里插入图片描述
会发现我们这里打开了一个json文件(我这里用了JSON-Handle,所以视图看起来是这样的)
在这里插入图片描述
而打开的这个文件,可以看到和这里的package.json是相同的

而在这里也可以看到,其中的dependencies是使用到了vue3.0.2版本,所以我们可以看到在App.vue中已经使用了vue3.0的特性

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3.0 + Vite" />
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

这里可以看到,template标签下是不止一个标签的,这正是vue3.0的其中一个特性

vite的工作机制

既然使用vite启动项目了,那么接下来我们就要透过vite启动的这个项目来了解vite的工作机制了

首先,我们要知道的是,vite整体的工作机制,可以简单地看一下下图
在这里插入图片描述
由图我们也可以看到,vite实际上也是一个server,在启动vite构建web server(就是上面的localhost:3000)后,我们访问这个地址,该页面会向web server发送请求,请求对应的文件,我们可以从network中看到,如下
在这里插入图片描述

在请求这些资源后,这些资源并非是直接返回的,我们可以看看其中的App.vue,实际上可以看到,这里有两个App.vue,两个HelloWorld.vue,实际上这就是因为在我们请求这些文件的时候,被vite server拦截了,经过编译后才返回对应的内容

我们可以看看network中App.vue的内容
在这里插入图片描述
可以看到和项目中的App.vue其实是完全不同的
在这里插入图片描述
但仔细看的话会发现,在network中的App.vue,有一句

import { render as __render } from "/src/App.vue?type=template"

引入了App.vue?type=template,而再看App.vue?type=template的请求得到的Response,我们可以发现,实际上这就是App.vue中template的内容
在这里插入图片描述
而实际上,这个工作机制也正是vite快的原因,在这里,由于视图只会请求到他使用到的文件,而vite只会拦截被请求到的文件,所以那些没有被引用到的文件就不会被编译,这就做到了按需编译

我们这里可以尝试修改main.js中的import的内容,不引入css文件

import { createApp } from 'vue'
import App from './App.vue'
// import './index.css'

createApp(App).mount('#app')

此时页面自动刷星,可以看看network的内容,发现没有请求index.css文件
在这里插入图片描述
但这样子,有的同学可能会提出一个问题,每次请求都拦截编译一次,不会造成多次重复的编译工作吗,这里我们可以仔细地看看图中,会发现,除了main.js和client,以及一个用来改变协议的websocket握手外,状态码都变成了304
在这里插入图片描述
304是什么?缓存啊,这样就意味着,当我们修改了页面的内容的时候,它只会重新编译其中发生了改变的文件,而其他文件通过缓存的方式,直接使用缓存资源,不需要进行额外的编译,这也是直接利用了浏览器的缓存机制

除了利用浏览器缓存外,vite本身也有一个缓存的机制,它会针对依赖的包做一个缓存,这里我们可以看一下network中main.js的response
在这里插入图片描述
可以发现,我们对vue的引用,变成了对@modules下的vue.js的引用,那么这个vue.js,是在哪里呢
我们回到项目的目录,找到node_modules下的.vite_opt_cache文件夹可以找到vue.js文件
在这里插入图片描述
而实际上,network中的vue.js文件,就是这个文件,这个是一个对vue进行编译后生成的js文件,如何证明我们最终请求到的是这个文件呢,其实也简单,我们直接在这个文件中添加一些代码
在这里插入图片描述
这里我们在第9行添加了一个注释,回到network中查看,可以发现,并没有发生任何改变,但实际上,这是因为这个文件的修改不会造成热更新,所以我们需要ctrl+R刷新一下
在这里插入图片描述
可以看到,果然出现了,实际上.vite_opt_cache就是用来存放被缓存的依赖包的,而这里不止缓存vue的依赖包,其他的依赖包也可以,比如这里我们引入一个axios

npm i axios -S

在main.js中简单加入一个axios请求(这里只是随便写个请求让axios能被用到)

import { createApp } from 'vue'
import App from './App.vue'
import axios from "axios"
// import './index.css'

axios.get("https://www.baidu.com")
createApp(App).mount('#app')

刷新根目录,可以看到,.vite_opt_cache下多了一个axios.js
在这里插入图片描述
vite就是通过这两种缓存,又一次提升了速度

等等,刚刚我们说了啥,websocket连接,怎么会有websocket连接,这个hello world页面好像没有什么websocket相关的东西啊,实际上,这是vite实现HMR的手段
vite通过使用websocket连接,当我们修改一个文件保存时,将这个修改的文件编译推送到浏览器,实现一个热更新,具体实现我们可以留待后面讲和websocket的比较以及实现一个简单的vite的时候来讲,这个时候先知道它是一个实现HMR的一个方式就可以了

那么到这里,我们基本了解完vite的使用和其整体的工作机制了,接下来就是要通过和webpack比较,看看vite给我们带来了什么比webpack更好的东西,什么情况下要用vite,什么情况下又要用webpack,下篇文章即将出炉,敬请期待

Logo

前往低代码交流专区

更多推荐