• 作者:老汪软件技巧
  • 发表时间:2024-10-30 21:03
  • 浏览量:

废话不多说,说了也没人看

直接开始吧

基础项目搭建

首先,从0建立一个最基础的vite项目

html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <script src="./main.js" type="module">script>
body>
html>

npm install lodash

import _lodash from "lodash"
console.log('这是lodash库', _lodash);

这时我们打开浏览器页面,查看控制台,会发现有报错:

image-20241028113535141.png

意思就是找不到这个库在哪里,所以无法导入,要使用绝对路径或者相对路径去导入才行

模块导入的路径问题

使用名称导入失败了

这是为什么呢?

这就牵连到commonJS和**ESM(ES Modules)**之间的关系了

在浏览器中原生是不支持CommonJS的,这是因为CommonJS 适用于加载本地模块,是一个同步加载的过程,比如Node.js 中加载模块其实是一个读取本地文件并执行的同步过程,而在浏览器中要获取资源通常是需要异步请求获取的。

当我们安装了库的时候,会安装到node_modules文件中,例如我们安装的lodash.js(因为我使用的时pnpm,因此文件目录与npm安装的有些许不同,但无妨):

image-20241028131422565.png

在我们只使用名称去导入的时候,浏览器是没办法去node_modules文件中查找,因为**浏览器是没有文件夹(文件系统)**这个概念的,浏览器中的 ESM 只支持 ./、../ 或绝对路径作为导入路径,而 import _ from 'lodash' 这样的形式在浏览器中无法找到对应文件。

但是我们不可能每个依赖库都使用相对路径/绝对路径去导入,这样极其繁琐。因此我们需要一个工具来帮助我们快速导入,这就用到了vite,webpack等这类打包构建工具了。

这里我们使用vite

安装Vite

vite的特性之一就是开箱即用(out of the box)

我们直接安装一波:

$ npm install -D vite

或者使用pnpm

pnpm add -D vite

安装完之后,我们需要到package.json文件中添加配置:

添加"dev":"vite"(如果package.json文件中没有"scripts":{}的话可以自行添加)

image-20241028143317794.png

导入完成之后,启动项目:

npm run dev
//或
pnpm run dev

运行成功,在原本报错的语句中,也正常运行

image-20241028143844996.png

这说明vite导入成功,并且帮助我们导入了lodash.js

我们在浏览器调试工具中打开网络一栏,会看到浏览器请求了lodash.js

image-20241028144142327.png

[图文并茂] 面试官:说一下Vite依赖预构建的原理_[图文并茂] 面试官:说一下Vite依赖预构建的原理_

因此,浏览器能够获取到lodash.js,就能够打印出来

值得一提的是,vite帮助我们把导入的库规范化,符合ES规范,使浏览器能够正常使用和运行。不过在本例子中的lodash.js已经是非常规范化的了,就不需要vite再去处理。

image-20241028144711057.png

依赖预构建

这时候又引出另一个问题:

当我们引入一个库的时候,这个库往往可能会依赖其他的库,那这种情况如何处理?

在这种情况下,vite会将他们集成在一起

我们来实操证明一下:

我们现在来安装另一个版本的lodash.js库

npm install lodash-es
//或
pnpm add lodash-es

安装成功后,在main.js中导入(为方便理解,注释之前的lodash)

// import _lodash from "lodash"
import _lodash_es from "lodash-es"
// console.log('这是lodash库', _lodash);
console.log('这是lodash-es库', _lodash_es);

运行之后查看浏览器中的打印情况和网络请求的包情况

image-20241028151527736.png

image-20241028151557023.png

我们查看浏览器中导入的lodash-es.js,会发现这和我们在项目中导入的不一样,我们大致对比一下:

image-20241028151911162.png

源文件中导入了非常多的库,这里为了方便,就只展示这些,大家应该也能够理解了

接着,我们更进一步去更加直观的了解一下vite给我们的帮助

首先在根目录下建立一个vite.config.js文件写入以下配置,配置的意思为

export default {
    optimizeDeps: {
        exclude: ['lodash-es'],
    },
};

然后进入浏览器中查看网络请求

务必重启项目,再进入浏览器中查看网络请求

image-20241028163734762.png

可以非常直观的看到,浏览器加载了超级超级多的依赖库出来!

对比之前我们使用vite的时候只有一个包,体验是不是好很多?!

vite帮我们将这些导入的库都集成在一个文件中了,这样方便浏览器去导入

预构建工作原理:

总而言之:

在vite开发模式下,会扫描项目的依赖,识别出所有CommonJS模块,这些模块会通过Vite内部的依赖预构建功能使用esbuild转成ESM规范的格式

预构建完成之后,这些依赖会被缓存到node_modules/.vite目录下,方便浏览器加载的时候直接使用ESM规范的格式

至此

vite解决了三个问题:

不同的第三方库会有不同的导出格式,vite会处理成符合浏览器规范的格式路径处理,可以使用非绝对/非相对路径方便重写处理网络多包传输的性能问题(解决原生ES Module不敢支持node_modules的原因之一)