目录
1. Webpack 的构建原理
2. Script 的模块化(主流浏览器对 ES Modules 的支持)
3. Webpack vs Vite
开发模式的差异
对 ES Modules 的支持
底层语言的差异
热更新的处理
1. Webpack 的构建原理
前端之所以需要类似于 Webpack 这样的构建工具,是为了提高项目的开发效率,Webpack 通过分析 js 中的 require 语句,分析出当前 js 文件所有的依赖文件,通过递归的方式层层分析后,得到整个项目的依赖关系图,对图中不同的文件执行不同的 loader,比如使用 css-loader 解析 css 代码,最后基于这个依赖关系图读取到整个项目中的所有文件代码,进行打包处理之后交给浏览器执行。
这样的构建过程,导致了在我们调试代码之前,需要等待 Webpack 的依赖收集过程,而当项目代码体量很大时,这个依赖收集的过程往往需要我们等待几十秒甚至一两分钟,程序员在这个时间段内只能摸鱼,开发体验非常差,有什么办法解决这个问题?
如果有办法能够做到更少的代码打包就好了!!!于是 bundless 的打包思路就诞生了,Vite 便是这种思路的遥遥领先。
2. Script 的模块化(主流浏览器对 ES Modules 的支持)
需要打包工具的核心原因,就是浏览器在执行代码的时候,本身没有一个很好的方式去读懂我们的项目中的各个文件引入关系。
所以 Webpack 对浏览器说:“你别纠结了,我把所有的文件引入关系都梳理好了,并且将项目中所有文件的代码打包在了一起,你就去执行找一个文件吧!”
浏览器开心地说:“好的大哥,谢谢大哥”,然后毫无压力的哐哐运行
但是随着浏览器的进步,它开始能慢慢读得懂一些模块化的引入语法了,比如:
add.js
export const add = (a, b) => {return a + b
}
main.js
import { add } from './add.js'
console.log(add(1,3))
test.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script type="module" src="./main.js"></script>
</body>
</html>
vs code 中 test.html 文件鼠标右键 Open with Live Server 打开,浏览器是可以正常运行这份代码的:
浏览器会将 import 语句处理成一个个 HTTP 网络请求,去获取 import 引入的各种模块, 就因为浏览器现在可以通过 type="module" 这种方式读懂项目中文件的模块化引入。Vite正基于此。
3. Webpack vs Vite
-
开发模式的差异
在开发环境中,Webpack
是先打包再启动开发服务器;Vite
则是直接启动,然后再按需编译依赖文件。
这意味着:
当使用
Webpack
时,所有的模块都需要在开发前进行打包,这会增加启动时间和构建时间。而
Vite
则采用了不同的策略,它会在请求模块时再进行实时编译,这种按需动态编译的模式极大地缩短了编译时间,特别是在大型项目中文件数量众多,Vite
的优势更为明显
-
对 ES Modules 的支持
现代浏览器本身就支持 ES Modules
,会主动发起
请求去获取所需文件。Vite 充分利用了这一点,将开发环境下的模块文件直接作为浏览器要执行的文件,而不是像 Webpack 那样先打包
,再交给浏览器执行。这种方式减少了中间环节,提高了效率。
-
底层语言的差异
Webpack 是基于 Node.js
构建的,而 Vite 则是基于 esbuild
进行预构建依赖。esbuild 是采用 Go
语言编写的,Go 语言是纳秒
级别的,而 Node.js 是毫秒
级别的。因此,Vite 在打包速度上相比Webpack 有 10-100
倍的提升。
预构建依赖通常指的是在项目
启动或构建
之前,对项目中所需的依赖项进行预先的处理或构建
。这样做的好处在于,当项目实际运行时,可以直接使用
这些已经预构建好的依赖,而无需再进行实时的编译或构建,从而提高了应用程序的运行速度和效率。
-
热更新的处理
在 Webpack 中,当一个模块或其依赖的模块内容改变时,需要重新编译
这些模块。而在 Vite 中,当某个模块内容改变时,只需要让浏览器重新请求
该模块即可,这大大减少了热更新的时间。