vite的快的原因居然如此简单!探秘其依赖预加载机制

简介: 【8月更文挑战第1天】探秘vite预加载机制

为什么需要vite

我们创建一个index.html文件,在里面引入main.js,在main.js中引入counter.js

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
  </head>
  <body>
    <script src="./main.js" type="module"></script>
  </body>
</html>

main.js

import { count } from"./counter.js"
console.log(' count: ',  count);

counter.js

export const count = 0;

我们在浏览器中打开,控制台会正常输出console的内容,这是没有问题的。

但是,如果,我们使用插件的方式在counter.js中引入npm包呢?

npm i lodash
import _ from "lodash"; 
console.log("lodash", _);
export const count = 0;

这时,浏览器会报错

因为浏览器只识别相对路径或者绝对路径,import _ from "lodash"的方式浏览器是无法识别的。

那为什么浏览器在我们导入非绝对路径和非相对路径的资源的时候不默认帮我们?

各个模板之间是相互依赖的,如果浏览器帮我们识别引入,会导致浏览器需要加载非常巨大的依赖文件,会让其速度非常慢!

这个时候,我们就可以借助vite来帮我们实现了,它是开箱即用的。

引入vite

npm i vite -D

我们在package.json中增加一下vite的快捷使用命令

"scripts": {
    "dev": "vite"
  },

然后再命令行启动 npm run dev,可以看见项目成功启动

打开网页,也可以发现代码正常执行了(执行代码:console.log("lodash", _);     )。

真是开箱即用啊!!

vite的预加载

vite能够识别非绝对路径或者相对路径的引用,是因为它进行了路径补全。打开控制台,我们可以看到答案

lodash的加载路径变成了node_modules/.vite/deps/lodash.js?v=1484ebe8。可以发现,vite对loadsh进行了预处理,并把它放在了node_modules/.vite/deps目录下。

为什么要采用这种加载方式呢?

实际上,是vite在考虑另外一个问题的时候顺便把这个问题解决了!

我们知道,有些包是以commonjs 规范导出的,这导致浏览器是无法识别这种导出格式的,因此,vite针对此问题,进行了依赖预构建

依赖预构建

首先vite会找到项目中所需要的依赖,然后调用esbuild(对js语法进行处理的一个库),将其他规范的代码转换成esmodule规范;然后放到node_modules/.vite/deps文件夹下;同时对esmodule规范的各个模块进行统一集成 。

这种设计思想解决了三个问题:

  • 将不同规范导出的包统一成了esmodule规范
  • 对路径的处理上可以直接使用.vite/deps,方便路径重写
  • 解决了网络多包传输的性能问题

依赖预构建的优点

我们通过一个例子里看看依赖预构建的优点。

预构建对代码的处理

我们安装lodash-es来看看

npm i lodash-es -D

我们在main.js中引入lodash-es,然后进入lodash-es源码部分

import { count } from"./counter.js"
import lodashES from "lodash-es"
console.log('lodashES: ', lodashES);
console.log(' count: ',  count);

可以看出,lodash主入口文件里,导出了许多基于es规范的函数

但是,我们打开浏览器看看,会发现,这里的代码被vite进行了处理放在了/node_modules/.vite/deps目录下

我们可以总结出vite做的处理

  • 将处理好的文件放在了/node_modules/.vite/deps目录下
  • 对esmodule规范的各个模块进行统一集成(将分散的导出函数放在了一个文件里) 。

我们来看一下,如果不对esmodule规范的各个模块进行统一集成,会发生什么。

关闭依赖预构建

我们在项目根目录创建vite..config.js,通过配置,关闭lodash-es的项目预构建。

import { defineConfig } from "vite";
export default defineConfig({
    optimizeDeps: {
        exclude: ["lodash-es"], // 将指定数组中的依赖不进行依赖预构建
    },
});

此时,打开浏览器控制台,可以清除的看到lodash-es的请求地址变成了实际地址。

显然,lodash-es的预构建被关闭了。但是,此时,所有的es相关依赖都被加载了。

仅仅一个lodash-es就让浏览器多请求了如此多的文件!这也是原生esmodule规范不敢支持node_modules的原因之一。

vite依赖预构建的优点

可见,有了依赖预构建以后无论他有多少的额外export 和import,vite都会尽可能的将他们进行集成最后只生成一个或者几个模块

相关文章
|
4月前
|
Web App开发 JavaScript API
告别滚动卡顿:现代化图片懒加载方案实战
告别滚动卡顿:现代化图片懒加载方案实战
200 78
|
JavaScript 应用服务中间件 nginx
【报错】nginx部署项目后Echarts折线图无法展示
在Vue3+TS+Arco项目中,打包后使用Nginx部署的Echarts折线图显示异常,报`Cannot read properties of undefined(reading &#39;setOption&#39;)`错误。问题源于在定义div时使用了Vue2的`$refs`语法,导致DOM元素无法正确初始化Echarts。解决方法有两种:1) 不推荐使用`document.getElementById`获取DOM并初始化Echarts;2) 推荐在Vue3中通过`ref`获取DOM,在`onMounted`中使用`echarts.init`并借助`nextTick`异步绘制数据。
345 3
|
缓存 JavaScript 前端开发
手写vite让你深刻了解Vite的文件加载原理
【8月更文挑战第3天】 手写vite让你深刻了解Vite的文件加载原理
353 4
手写vite让你深刻了解Vite的文件加载原理
|
11月前
|
移动开发 Unix Linux
拉取代码编辑器中报错`Delete ␍ prettier/prettier` 问题的解决方案
通过正确配置Prettier、EditorConfig文件和编辑器设置,可以有效解决 `Delete ␍ prettier/prettier`的问题。这不仅能避免频繁的格式化错误,还能确保团队成员在不同开发环境下的代码风格一致,提升项目的代码质量和可维护性。按照上述解决方案调整配置后,您的项目将更加规范,代码也会更具一致性。
958 4
|
JavaScript 前端开发 开发者
太爽了!这10个 Vite 插件,帮我在开发中节省了大量时间!!
太爽了!这10个 Vite 插件,帮我在开发中节省了大量时间!!
|
存储 容灾 关系型数据库
OceanBase 高可用性架构解析
【8月更文第31天】在大数据和云计算蓬勃发展的今天,数据库作为数据存储的核心组件,其稳定性和可靠性直接影响到整个系统的性能。OceanBase 是由阿里巴巴集团自主研发的一款分布式关系型数据库系统,旨在为大规模在线交易处理(OLTP)场景提供高性能、高可用性的解决方案。本文将深入探讨 OceanBase 是如何通过其独特的架构设计来确保数据的高可用性和容灾能力。
596 0
vue3 watch 监听多值以及深度监听用法
vue3 watch 监听多值以及深度监听用法
2659 0
|
JavaScript
【vue】 vue中判断路由变化 | 监听路有变化
【vue】 vue中判断路由变化 | 监听路有变化
130 0
|
缓存 前端开发 JavaScript
【专栏:HTML与CSS移动端开发篇】移动端网页性能优化策略
【4月更文挑战第30天】本文探讨了移动端网页性能优化的重要性,并提出了优化策略。HTML方面,建议精简结构、使用语义化标签、异步加载脚本和压缩文件;CSS优化包括精简样式、使用CSS3动画、媒体查询和压缩文件。其他策略涉及图片和字体压缩、缓存利用、数据压缩、减少HTTP请求及根据网络状态调整加载。综合运用这些策略能提升网页性能和用户体验。
270 6
|
设计模式 消息中间件 供应链
捕捉变化的风-用观察者模式提升用户体验
观察者模式是一种行为设计模式,允许对象之间定义一种订阅机制,以便在对象状态变化时通知多个观察者。它广泛应用于实现动态事件处理系统、用户界面元素的交互,或监测状态变化等场景。 文章中通过丰富的场景案例,展示了不使用观察者模式可能带来的问题,如紧耦合和难以维护;接着解释了如何应用观察者模式成功解决这些问题,通过主题和观察者的解耦,增强系统的灵活性和可扩展性。 进一步解释了观察者模式的工作原理,并介绍了其结构图和运行机制。该模式有助于在维护一致性和实时性方面提供优势,同时促使我们在高层次上分类对象间的交互。 最后
329 0
捕捉变化的风-用观察者模式提升用户体验