Files
zhuangang/topics/frontend/vite/scenarios/webpack-to-vite.md
T

3.6 KiB
Raw Blame History

id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week
id title type domain stack tags level prerequisites est_hours related week
frontend.vite.scenario.webpack-to-vite 老项目从 webpack 迁移到 Vite:评估、步骤、风险和回滚 scenario frontend
vite
webpack
迁移
构建工具
CommonJS
环境变量
灰度
intermediate
frontend.vite.dev-build-config
frontend.webpack.build-optimization
2
frontend.vite.interview
frontend.webpack.interview
7

老项目从 webpack 迁移到 Vite:评估、步骤、风险和回滚

业务背景与问题

一个 5 年的 Vue 2 → Vue 3 后台项目(几百个页面)仍用 webpack 4 构建:开发启动要几分钟,改一行代码热更新要十几秒,团队抱怨效率低;依赖老旧,有安全漏洞告警。

约束

  • 不能停止业务需求开发,迁移要渐进。
  • 有自定义的 webpack loader(处理内部 SVG 图标)和 process.env.XXX 的大量使用。
  • 线上不能出问题,要可以回滚。

方案设计

  1. 评估:列出 webpack 配置中所有的 loader / plugin,逐个找 Vite 对应方案(多数有现成插件);扫描代码中的 require()、require.context、process.env、module.hot。
  2. 并行配置:先新增 vite.config.ts,与 webpack 配置并存,开发者可以选择用哪个启动;CI 两种都构建。
  3. 逐项替换:
    • require.context → import.meta.glob;
    • process.env.VUE_APP_XXX → import.meta.env.VITE_XXX(批量替换 + 类型声明);
    • 自定义 loader → Vite 插件的 transform 钩子;
    • 别名、代理配置平移。
  4. 验证:页面冒烟测试(Playwright 跑核心流程);对比两份构建产物的体积和关键页面性能指标。
  5. 灰度上线:先上测试环境,再让部分流量使用新产物;保留 webpack 构建一个迭代周期,出问题可以切回。

关键代码

// webpack:const modules = require.context("./icons", false, /\.svg$/);
// Vite:
const icons = import.meta.glob("./icons/*.svg", { query: "?raw", import: "default", eager: true });

// 自定义 loader 改写为插件
function svgIcon(): Plugin {
  return {
    name: "svg-icon",
    transform(code, id) {
      if (!id.endsWith(".svg?icon")) return null;
      return { code: `export default ${JSON.stringify(optimizeSvg(code))};`, map: null };
    },
  };
}

可运行的 Vite 配置:examples/vite-config。

取舍

选择 优点 缺点
迁移到 Vite(本方案) 开发体验大幅提升、配置简单 迁移成本、部分 webpack 专有特性需要替代
升级 webpack 5 + 缓存 + 更快的 loader(如 swc-loader) 改动小 开发启动仍然慢于 Vite
Rspack(兼容 webpack 配置的 Rust 构建工具) 配置几乎不用改 生态兼容性需要验证

易错点

  • 只验证开发模式,没有验证生产构建。
  • 批量替换环境变量时遗漏了第三方库读取的 process.env.NODE_ENV(Vite 构建时会自动替换这个,但其他 process.env 引用不会)。
  • 迁移后 chunk 的划分和文件名变化导致 CDN 缓存策略失效。
  • 一次性切换,没有回滚方案。

面试怎么讲

“我主导过一个老项目从 webpack 迁到 Vite。先盘点配置和代码中的 webpack 专有用法,然后两套配置并存、CI 都构建,逐项替换 require.context、环境变量和自定义 loader;用 Playwright 跑核心流程冒烟,对比产物体积和性能指标;灰度上线,保留旧构建一个迭代。结果是开发启动和热更新明显变快(具体数字以你的项目实测为准)。”