Vite的概念及设计思想

147 阅读3分钟

由两部分组成

  • 一个开发服务,服务于开发环境,ESM+HMR
  • 一套构建指令,服务于生产环境,用Rollup打包

什么是打包

使用工具抓取、处理并将我们的源码模块串联成可以在浏览器运行的文件

常用前端打包构建工具

  • webpack
  • rollup
  • parcel
  • gulp

webpack的缺点

webpack需要遍历整个应用程序,从入口文件开始,把其依赖的所有文件都打包成bundle.js,然后devServer会把js文件传递给客户端的浏览器进行展示。每一次我们修改并保存,都会促发这样一个流程,大型项目消耗大量时间。

传统打包器

image.png

ESM打包器

Vite原生支持ESM,浏览器发出HTTP请求,请求响应的entry文件,如果只用到当前文件,它就不会去加载其他文件,只用到当前页面依赖的模块,这样就避免了每次构建都要打包所有文件。类似于按需加载

image.png 💥那么Vite是如何实现上述模式的呢?

Vite将模块区分为依赖和源码

  • 依赖:开发时不变动的纯js,相当于node_modules文件下的模块,Vite会使用esbuild预构建依赖,esbuild使用go语言编写,效率高
  • 源码:包括一些非原生js文件,如.jsx、.css、.vue文件等,这些文件经常会被编译,需要转换,基于路由对其进行拆分,这样就可以避免重复打包,Vite以原生ESM方式提供源码,让浏览器接管打包工作,浏览器请求时按需提供源码,根据具体情境在当前页面被使用到才会被处理

源码模块可能会进行协商缓存,依赖模块会进行强缓存,这样请求速度会更快,应用启动会更快

esm加载对比

接下来我们做一个浏览器原生加载ESM模块的实验

新建index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ESM Browser</title>
    <!-- 引入main.js文件,类型为module -->
    <script src="main.js" type="module"></script>
</head>
<body>
    
</body>
</html>

引入lodash包

yarn add lodash-es

从lodash中引入filter方法

// 从lodash中引入filter方法
import { filter } from 'lodash-es'

let students = [{ name: tom, age: 20 }, { name: jerry, age: 30 }]
let filterStudent = filter(students, student => student.age > 20)
console.log(filterStudent)

image.png

💢出现错误,这是因为浏览器加载模块需要路径,我们修改一下引入路径,改成./node_modules/lodash-es/lodash.js

image.png

❗打印出来了 成功❗

查看一下network,发现加载了lodash.js中所有导入的文件,lodash.js中如 export { default as add } from './add.js' 相当于两个操作,先import再export,而浏览器遇到import就是请求模块,所以所有都被请求了,太多无效请求了,那么Vite是如何解决的呢

image.png

❤Vite的解决方法

初始化一个Vite项目,选用原生js;选择Vanilla

yarn create vite

同样像上面一样安装lodash-es,并修改 main.js文件,浏览器控制台依然正常打印,可以看到文件变少了

image.png

查看一下main.js,发现路径被vite修改了,vite对其进行了处理

image.png