Webpack 和 Vite 都是前端构建工具,但它们在设计理念和实现方式上有较大的区别。
Webpack 是一种模块打包工具,主要功能是将各种资源(如 JavaScript、CSS、图片等)通过 loader 和 plugin 转换和打包成可以直接在浏览器中运行的代码。其核心思想是以代码分割、按需加载和优化资源来提升性能。
Vite 是一种新型构建工具,利用原生 ES 模块(ESM)和现代浏览器特性,提供快速开发和构建体验。Vite 的核心思想是在开发环境中直接利用浏览器的 ESM 功能,以提升启动和热更新速度。
Webpack 的优缺点:
优点:
- 高度可配置,可以应对各种复杂的项目需求。
- 社区资源丰富,有大量的 loader 和 plugin 可以使用。
- 得到了广泛的应用和支持,在生产环境中非常成熟和稳定。
缺点:
- 配置较为复杂,新手上手难度较高。
- 开发环境下的编译速度较慢,尤其是在大项目中。
- 热更新(HMR)速度不够理想。
Vite 的优缺点:
优点:
- 开发服务器启动速度快,因为它基于现代浏览器的 ESM 处理。
- 热更新(HMR)速度非常快,几乎是瞬时的。
- 开箱即用,配置较为简单,适合小型和中型项目。
缺点:
- 生态系统相对不如 Webpack 丰富,某些复杂需求可能需要自定义解决方案。
- 在某些特殊环境下可能会遇到兼容性问题。
- 生产环境中打包速度和 Webpack 相差无几,但没有 Webpack 那么成熟。
为什么Vite启动快
Vite在开发环境下,就先用了esbuild预构建依赖,比如node_modules里一些包先转换成ESM后再确定依赖关系。并且生产环境下,vite也利用了esbuild的代码转换功能,相较于webpack的babel快了很多。
而Esbuild之所以能这么快,主要原因:Go 语言开发,可以多线程打包,代码直接编译成机器码;相应的,webpack存在大量的 resolve、load、transform、parse 操作,而这些操作通常是通过 javascript 代码来执行的。而JS是单线程的,esbuild可以在Go环境的优势下,完成自己内部的transform和build操作,速度会快很多。
http2
vite充分利用了http2可以并发请求的优势,这也是速度快的一个主要原因。 接下来,我们了解一下http2的来龙去脉。
在之前http1的时候,浏览器对同一个域名的请求,是有并发限制的,一般为6个,如果并发请求6个以上,就会造成阻塞问题,所以在http1的时代,我们要减少打包产物的文件数量,减少并发请求,来提高项目的加载速度。
2015年以后,http2出现了,他可以并发发送多个请求,不会出现http1的并发限制。这时候,将打包产物分成多个小模块,并行去加载,反而会更快。
vite也充分利用了这一优势,对项目资源进行了合理的拆分,访问项目时,同时加载多个模块,来提升项目访问速度。
Vite 支持直接导入静态资源,如图片、字体等,无需经过Webpack的处理
webpack必须配合require或者loader来处理静态资源,而vite可以直接导入,并且会自动处理。
//webpack:
<img class="size" :src="require('@@/assets/img/radio_checked.png')" />
//vite:
import homeBg from 'src/assets/images/home/home_bg.png'
<img :src="homeBg" />
webpack和vite的启动方式
webpack 原理图
当我们使用webpack启动项目时,webpack会根据我们配置文件(webpack.config.js) 中的入口文件(entry),分析出项目项目所有依赖关系,然后打包成一个文件(bundle.js),交给浏览器去加载渲染。
这样就会带来一个问题,项目越大,需要打包的东西越多,启动时间越长
vite 原理图
- webpack: 分析依赖=> 编译打包=> 交给本地服务器进行渲染。首先分析各个模块之间的依赖,然后进行打包,在启动webpack-dev-server,请求服务器时,直接显示打包结果。webpack打包之后存在的问题:随着模块的增多,会造成打出的 bundle 体积过大,进而会造成热更新速度明显拖慢
- vite: 启动服务器=> 请求模块时按需动态编译显示。是先启动开发服务器,请求某个模块时再对该模块进行实时编译,因为现代游览器本身支持ES-Module,所以会自动向依赖的Module发出请求。所以vite就将开发环境下的模块文件作为浏览器的执行文件,而不是像webpack进行打包后交给本地服务器。
- 分析了webpack和vite的打包方式后,也就明白了为什么vite比webpack打包快,因为它在启动的时候不需要打包,所以不用分析模块与模块之间的依赖关系,不用进行编译。这种方式就类似于我们在使用某个UI框架的时候,可以对其进行按需加载。同样的,vite也是这种机制,当浏览器请求某个模块时,再根据需要对模块内容进行编译。按需动态编译可以缩减编译时间,当项目越复杂,模块越多的情况下,vite明显优于webpack。
- 热更新方面,效率更高。当改动了某个模块的时候,也只用让浏览器重新请求该模块,不需要像webpack那样将模块以及模块依赖的模块全部编译一次。
扩展知识
在前端开发中,选择合适的构建工具对于开发效率和最终产品性能非常重要。下面是一些更深层次的思考:
-
现代前端架构趋势:
- 随着前端项目越来越复杂,对构建工具的要求也越来越高。这不仅仅是打包和压缩代码,还包括模块化、代码分割、按需加载等功能。
-
Webpack 的细节和进阶技巧:
- Webpack 的 loader 和 plugin 系统是其灵活性的关键,理解其工作原理和最佳实践(如设置 caching、tree shaking、代码分割等)可以大大提升项目性能。
- 使用 Webpack 的 DevServer 以提升开发体验,反向代理等功能在开发过程中也非常实用。
-
Vite 的创新设计:
- Vite 不仅能支持现代浏览器的 ESM,还能通过插件系统实现诸如热模块替换(HMR)、环境变量注入等高级功能。
- Vite 的插件系统同样强大,类似于 Rollup 的插件机制,使得开发者可以快速拓展功能。
-
兼容性和社区支持:
- Webpack 拥有庞大的社区和丰富的第三方插件几乎可以解决所有的问题。
- Vite 虽然起步较晚,但在 Vue 社区的带动下增长迅速,未来潜力巨大。