云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

为什么 Vite 还没有完全替代 Webpack?

jxf315 2025-10-19 06:58:01 教程文章 1 ℃

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

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

Tags:

最近发表
标签列表