vite
是一个开箱即用的构建工具,不需要做任何额外的配置就可以使用vite
来帮你处理构建工作,在默认情况下我们的esmodule
去导入成依赖的时候,要么是绝对路径,要么是相对路径,例如下面这个例子
import { count } from './counter.js'
但是在vite
中,支持根据依赖名直接引入,例如:
/* 安装 npm i lodash */
import _ from 'lodash'; // 报错
import _ from 'lodash';
这种根据依赖名直接引入,js
是不支持的,系统提示需要给一个依赖路径。但是我们都知道,安装的依赖会在node_modules
中,既然我们现在依赖的最佳实践是node_modules
,那么为什么es
官方在我们导入非绝对路径和非相对路径的资源时,不默认帮我们搜寻node_modules
呢?
举个例子:
我们创建一个counter.js
,导出该文件,并在main.js
中引入该依赖。
// counter.js
export const count = 100;
// main.js
import { count } from './counter.js'
console.log(count); // 100
main.js
是通过http
下载下来的,counter.js
也是通过http
下载下来的,我们引入的依赖,浏览器都会发送http
请求,帮我们下载依赖。我们都知道,项目中的依赖基本上都在node_modules
中,而node_modules
的文件非常多,一些包会将它们的ES
模块构建作为许多单独的文件相互导入,下载一个包,浏览器就可能会发送上百个请求。例如:lodash-es
,这一个包就有超过600
个内置模块。当我们执行 import { debounce } from 'lodash-es'
时,lodash-es
可能import
了其他东西,文件的互相import
会导致浏览器发送成百上千的HTTP
请求!尽管服务器在处理这些请求时没有问题,但大量的请求会在浏览器端造成网络拥塞,导致页面的加载速度相当慢。
例如:
为什么common.js可以做呢,因为common.js是运行在服务端的
vite依赖预构建
在vite
中可以直接通过依赖名称引入依赖,这是因为vite
在依赖处理过程中,如果看到了有非绝对路径或者相对路径的引用,它会开启路径补全。例如:
import _ from 'lodash'
// 补全为
import _ from "/node_modules/.vite/lodash"
我们都知道,寻找依赖的过程是自当前目录向上查找,知道搜寻到根目录或者搜寻到对应依赖位置。但如果根目录嵌套了一层目录,vite
所谓的路径补全就失效了,因为它从根目录向下寻找的mode_modules
并不存在,也就找不到依赖了。
那么vite
是怎么解决的呢?
这里需要区分一个问题,生产环境和开发环境npm run dev
: 开发环境(每次依赖预构建重新构建的路径都是正确的)
生产环境 : vite
会交给rollup
库完成生产环境的打包(这里的路径不一定正确)
依赖预构建:首先vite
会找到对应的依赖,然后调用esbuild
(对js
语法处理的一个库),将其他规范的代码转换成esmodule
规范,然后放到当前目录下的node_module/.vite/deps
下,同时对esmodule
规范的各个模块进行统一集成。
它解决了3个问题:
1、不同的第三方包的导出格式问题
2、对路径的处理直接使用.vite/deps
,方便路径重写
3、网络多包的传输性能问题,有了依赖预构建以后,不论有多少个额外的export
和import
,vite
都会尽可能的将他们进行集成,最后只生成一个或几个模块。
// a.js
export default function a(){}
// b.js
// export { default as a } from './a.js
// vite重写
function a(){
// 将依赖挂载到函数内再导出
}
export a()
vite依赖预构建官方文档 (点击直达)