我们创建一个index.html文件,在里面引入main.js,在main.js中引入counter.js
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来帮我们实现了,它是开箱即用的。
npm i vite -D
我们在package.json中增加一下vite的快捷使用命令
"scripts": {
"dev": "vite"
},
然后再命令行启动 npm run dev,可以看见项目成功启动
打开网页,也可以发现代码正常执行了(执行代码:console.log("lodash", _); )。
真是开箱即用啊!!
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规范的各个模块进行统一集成 。
这种设计思想解决了三个问题:
我们安装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做的处理
我们来看一下,如果不对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的原因之一。
通过上面的示例,我们知道有了依赖预构建以后无论某个库有多少个export 和import,vite都会尽可能的将他们进行集成,最后只生成一个或者几个模块便于我们使用。