网站首页 > 教程文章 正文
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
1. 是什么原因让 Webpack 给了 Vite 机会
1.1 Webpack 局限性
Web 应用程序变得越来越复杂,打包构建消耗的内存也越来越多。
同时,Webpack 的性能取决于包的大小,因为该工具会在项目发生每次更改时整合所有依赖项和整个源代码,然后对其进行转译。因此,在最坏的情况下,打包可能需要几分钟的时间。即使是 Webpack 的 HMR 功能优势也不能解决问题。
- 配置复杂:Webpack 的配置相当复杂且耗时,尤其是对初学者不友好。
- 构建时间更长:在更复杂的项目中,Webpack 的打包速度可能会更慢,从而影响工作效率。
1.2 是什么让 Vite 崭露头角
为什么 Webpack 时代推崇打包,而 Vite 推崇不打包呢?
最主要的原因是 HTTP/2.0 实现了多路复用和首部压缩,解决了 HTTP/1.1 中队头阻塞的问题,因此通过资源合并压缩减少 HTTP 请求对页面加载性能不会有显著提升了。
其次,随着 Chrome 61 发布,各大浏览器都已经原生支持 ESM ,浏览器自己就可解析 imports ,无需自己再实现模块化。利用浏览器原生 ESM 最大的好处就是可以实现按需加载,不用打包了,构建时间复杂度 O(1),启动很快,只需要启动 devServer 即可。
借助 ESM 的优势,Vite 的优势凸显:
- 速度:Vite 利用浏览器中的原生 ES 模块,从而缩短编译时间,尤其是在开发阶段。
- 易于配置:该工具依赖于默认设置,与 Webpack 相比配置更加简单且耗时更少。
- 内置开发服务器:在更改代码时自动重新加载应用程序。
2. 为什么 Vite 没法取代 Webpack
2.1 Webpack 和 Vite 两者定位不同
Webpack core 是一个纯打包工具(对标 Rollup),而 Vite 其实是一个更上层的 工具链方案,对标的是 (Webpack + 针对 web 的常用配置 + Webpack-dev-server)。
2.2 Webpack 的场景支持更加复杂多变
Webpack core 只针对打包不预设场景,所以设计得极其灵活,比如:不局限于针对 Web 打包。
module.exports = {
target: 'node',
// 默认为 “browserslist” 或 “web”
// 还支持 webworker、electron、nwjs 等等
};
以上 target 配置指示 Webpack 为特定环境生成运行时代码。
同时值得注意的是,Webpack 运行时代码与开发者编写的代码不同,如果想要针对特定环境,则应该使用 Babel 等转译器转译代码,例如,源代码中有箭头函数,并且想要在 ES5 环境中运行捆绑的代码,此时 Webpack 不会在配置目标的情况下自动转译 。
虽然 Vite 也支持了 build.target 配置:
// vite.config.js
import {defineConfig} from 'vite';
export default defineConfig({
build: {
target: 'esnext',
// 可以设置为'esnext', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'es2022', 'chrome89', 'firefox89', 'safari14' 等
// 其他构建配置
},
});
但是,该配置最终只用于构建浏览器兼容目标(注意:只是浏览器)。默认值是一个 Vite 特有的值:'modules',这是指支持原生 ES 模块、原生 ESM 动态导入 和 import.meta 的浏览器。Vite 将替换 modules 为 ['es2020', 'edge88', 'firefox78', 'chrome87', 'safari14']
另一个特殊值是 'esnext' , 即假设有原生动态导入支持,并只执行最低限度的转译。转换过程将会由 esbuild 执行,并且此值应该是一个合法的 esbuild 目标选项。
除了 target 的区别外,Webpack 几乎所有可配置的环节都做成了可配置的。而 Vite 的选择是缩窄预设场景来降低复杂度,即将大部分常见的 Web 构建需求直接做成默认内置。由于内置,可以适当的增加各个环节之间的耦合来进一步降低复杂度。
因此,允许开发者根据特定项目的需求定制打包和资源打包过程,在大型复杂项目中特别有用。
关于这点,Vite 的作者尤雨溪在知乎做了如下的回答:
换言之 Vite 从一开始就不是冲着对标 webpack 100% 使用场景来的。这是一个目标场景 vs. 复杂度的取舍。有些场景,比如针对 Node 打包,本来就不属于 Vite 的目标场景(这个场景可以直接用 esbuild)。但是在纯 web 这个目标场景下,Vite 可以做到在对标 webpack 栈对等功能的前提下极大的降低配置复杂度和提升开发体验。
2.3 Vite 赖以生存的 ESM 在浏览器端的瓶颈
Webpack 的打包模式在项目本身源码模块数量极大 (>1000) 的情况下还是有一点优势的,因为浏览器在处理这个级别的并发请求上会产生阻塞。
当然,Vite 也有一定的优化手段,比如:动态导入、优化依赖、配置 Vite 的 build.rollupOptions 等等。
// 动态导入示例
const loadComponent = async () => {
const {default: Component} = await import('./Component');
return <Component />;
};
// 只引入 lodash 的特定功能
import {debounce} from 'lodash-es';
// vite.config.js
import {defineConfig} from 'vite';
export default defineConfig({
build: {
// output.manualChunks 来手动控制代码分割
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor';
// 将所有 node_modules 中的依赖打包到 vendor.js
}
},
},
},
},
});
当然,通常来说如果你一个路由下模块数到这个级别说明 代码分割 / 按需加载 没做好。
2.4 Webpack 生态繁荣
所以 Vite 到底能不能干掉 Webpack?
如 Vite 作者所说,不限定目标场景肯定不可能,这也不是 Vite 的目标。如果限定 Web 场景,其实也不会,因为 Webpack 体量太大,还有 Next 和 Gatsby 这种已经跟它强耦合的大玩家,肯定会对它持续投入,死是肯定死不了的。
// next.config.js
const path = require('path');
module.exports = {
webpack: (config, { isServer}) => {
// 1. 添加自定义的别名
config.resolve.alias['@components'] = path.join(__dirname, 'components');
config.resolve.alias['@styles'] = path.join(__dirname, 'styles');
// 2. 添加自定义的模块规则
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'], // 使用 SVGR 处理 SVG 文件
});
// 3. 如果需要,可以修改其他配置
if (!isServer) {
// 例如,您可以在客户端构建中添加某些插件
config.plugins.push(new SomeWebpackPlugin());
}
return config; // 返回修改后的配置
},
};
参考资料
https://career.comarch.com/blog/javascript-bundlers-is-it-worth-switching-from-webpack-to-vite
https://stackoverflow.com/questions/55040635/why-use-webpack-to-bundle-applications-that-run-in-node-environment
https://webpack.js.org/configuration/target/#root
https://webpack.js.org/concepts/targets/
https://cn.vitejs.dev/config/build-options.html#build-target
https://www.zhihu.com/question/477139054/answer/2156019180
https://v2.vitejs.dev/guide/dep-pre-bundling.html#file-system-cache
猜你喜欢
- 2025-10-19 前端错误可观测最佳实践_前端错误处理
- 2025-10-19 工作中,前端开发要看项目,怎么查看别人的js项目代码
- 2025-10-19 超趣味 Electron+Vue 贪吃蛇游戏Snake
- 2025-10-19 AI时代的全栈框架:独立开发者的机会与挑战
- 2025-10-19 (CAD集成到网页)网页查看CAD的SDK快速入门
- 2025-10-19 前端webpack从入门到精通视频教程文末下载
- 2025-10-19 CSS 定位详解_css定位方式
- 2025-10-19 React Server Component 从理念到原理
- 2025-10-19 比Webpack快700倍的Turbopack,到底快在哪?
- 2025-10-19 webpack之CLI(命令行接口)详细介绍
- 10-19前端错误可观测最佳实践_前端错误处理
- 10-19工作中,前端开发要看项目,怎么查看别人的js项目代码
- 10-19超趣味 Electron+Vue 贪吃蛇游戏Snake
- 10-19AI时代的全栈框架:独立开发者的机会与挑战
- 10-19(CAD集成到网页)网页查看CAD的SDK快速入门
- 10-19前端webpack从入门到精通视频教程文末下载
- 10-19CSS 定位详解_css定位方式
- 10-19React Server Component 从理念到原理
- 最近发表
- 标签列表
-
- location.href (44)
- document.ready (36)
- git checkout -b (34)
- 跃点数 (35)
- 阿里云镜像地址 (33)
- qt qmessagebox (36)
- mybatis plus page (35)
- vue @scroll (38)
- 堆栈区别 (33)
- 什么是容器 (33)
- sha1 md5 (33)
- navicat导出数据 (34)
- 阿里云acp考试 (33)
- 阿里云 nacos (34)
- redhat官网下载镜像 (36)
- srs服务器 (33)
- pico开发者 (33)
- https的端口号 (34)
- vscode更改主题 (35)
- 阿里云资源池 (34)
- os.path.join (33)
- redis aof rdb 区别 (33)
- 302跳转 (33)
- http method (35)
- js array splice (33)