Webpack迁到Vite第七节(一):全家桶移除 --- 配置文件与构建核心
本篇定位 :迁移到 Vite,首先消失的是两个配置文件(
vue.config.js+babel.config.js)和四个构建核心包(webpack/@vue/cli-service/@vue/cli-plugin-babel/@vue/cli-plugin-eslint)。本篇逐一拆解:它们原来做什么、Vite 中谁替代、替代后发生了什么变化。
思维导图
配置文件与构建核心移除
├── 1.1 移除的配置文件
│ ├── vue.config.js(310 行)→ vite.config.js(200 行,-35%)
│ └── babel.config.js → esbuild + plugin-legacy 接管
├── 1.2 构建核心(4 个)
│ ├── webpack → Vite(开发)/ Rollup(生产)
│ ├── @vue/cli-service → vite CLI
│ ├── @vue/cli-plugin-babel → 不需要 Babel 集成层
│ └── @vue/cli-plugin-eslint → ESLint 与构建解耦
└── 附录:Webpack vs Vite vs Rollup vs esbuild 分工图
1.1 移除的配置文件
vue.config.js(310 行)
vue.config.js 是 Vue CLI 时期的项目配置文件。它本质上是一个Webpack 配置的壳 ------Vue CLI 把 Webpack 的原始配置(webpack.config.js)封装了一层,提供更友好的 API。但内部仍然是完整的 Webpack 配置。
原文件结构拆解:
vue.config.js
├── 构建参数处理(~80 行)
│ ├── npm_config_custom_path 解析(含 jenkins 兼容)
│ ├── npm_config_api_path 解析
│ ├── npm_config_tag_name 解析
│ └── npm_config_brand_color 解析
├── CDN 配置(~30 行)
│ ├── externals 定义(vue/vue-router/vuex/axios)
│ └── CDN JS 路径(本地路径 /js/*.min.js)
├── configureWebpack(~80 行)
│ ├── plugins: IgnorePlugin/DefinePlugin/CopyWebpackPlugin/ProvidePlugin
│ ├── externals: 生产环境启用 CDN
│ └── resolve.alias: @ → src/
├── chainWebpack(~60 行)
│ ├── style-resources-loader 注入
│ ├── svg-sprite-loader 配置
│ ├── babel-loader 缓存
│ ├── webpack-bundle-analyzer 条件启用
│ └── terser 去除 console(生产环境)
├── css.loaderOptions(~20 行)
│ └── less 配置(javascriptEnabled/math/modifyVars)
├── devServer(~25 行)
│ └── port/proxy/static
└── 其他(~15 行)
├── productionSourceMap
├── lintOnSave
├── transpileDependencies
└── parallel
Vite 替代 :vite.config.js(200 行),代码量减少约 35%。所有功能被 Vite 原生配置项替代:
| vue.config.js 功能 | vite.config.js 替代 | 行数变化 |
|---|---|---|
| 构建参数解析 | process.env.npm_config_* 直接读取 |
80→10 行 |
| CDN externals | 改为 manualChunks vendor 拆分,继续利用浏览器缓存 |
30→10 行 |
| DefinePlugin | define 配置项 |
20→10 行 |
| CopyWebpackPlugin | Vite 插件 configureServer + closeBundle 钩子 |
30→10 行 |
| IgnorePlugin(moment locale) | Vite 自动处理(moment 2.29 已优化) | 3→0 行 |
| ProvidePlugin | 不再需要(ESM import 替代全局变量) | 4→0 行 |
| style-resources-loader | css.preprocessorOptions.less.additionalData |
10→5 行 |
| svg-sprite-loader | virtual module 插件(virtual:svg-icons) |
15→20 行 |
| less-loader 配置 | css.preprocessorOptions.less |
20→15 行 |
| babel-loader | 不再需要(esbuild 替代) | 3→0 行 |
| webpack-bundle-analyzer | rollup-plugin-visualizer |
5→5 行 |
| terser 去 console | esbuild.drop: ['console'] |
5→2 行 |
| devServer | server 配置项 |
25→15 行 |
| transpileDependencies | 不再需要(Vite 默认转译 node_modules) | 3→0 行 |
关键差异 :vue.config.js 是通过 chainWebpack 和 configureWebpack 两个入口间接修改 Webpack 配置。vite.config.js 是直接控制 Vite。前者是"壳套壳",后者是"直给"。这正是行数大幅减少的根本原因。
babel.config.js
原文件内容:
javascript
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
['@babel/preset-env', { useBuiltIns: 'usage', corejs: 3 }],
],
plugins: ['@babel/plugin-transform-runtime'],
}
逐行拆解(机制细节详见第七节(二)的 Babel 专题分析,此处只列结构与结论):
① module.exports = { ... } :Babel 配置文件的标准格式。执行顺序:plugins 先于 presets 执行 (组内:plugins 从前往后,presets 从后往前)------即先 @babel/plugin-transform-runtime,再按反序执行 presets:@babel/preset-env → @vue/cli-plugin-babel/preset。
② presets 数组:Preset 是一组预设的插件集合,相当于"套餐"------一个 preset 包含几十个插件,一次配置就能启用全部。
③ @vue/cli-plugin-babel/preset:Vue CLI 的 Babel 预设,包含 JSX 语法支持、装饰器语法支持(Vue 2 class-style 组件)和 Vue 特有的转换。
④ ['@babel/preset-env', { useBuiltIns: 'usage', corejs: 3 }]:核心转译配置。
| 参数 | 值 | 作用 |
|---|---|---|
useBuiltIns |
'usage' |
按需 polyfill:扫描源码用到的 ES6+ API,只引入对应的 core-js 模块 |
corejs |
3 |
指定 polyfill 来源为 core-js@3(覆盖 ES2015-ES2022 全部 API) |
⑤ plugins: ['@babel/plugin-transform-runtime'] :把 Babel 转译时生成的辅助函数(如 _classCallCheck)从"每文件内联一份"改为"共享 @babel/runtime 引用",消除跨文件重复。
总结:Babel 在这里做了三件事------Vue 语法支持(preset)+ 语法转译与按需 polyfill(preset-env)+ 辅助函数去重(transform-runtime)。
Vite 用 esbuild 替代了 Babel 的所有功能。esbuild 不需要 polyfill(目标浏览器已原生支持 ES6+ API),也没有 helper 重复问题(直接生成无 helper 的目标代码)。babel.config.js 整文件移除。
1.2 构建核心(4 个)------ 逐包深度分析
本册分析构建核心 4 个包;整个第七节系列合计移除 16 个包(本册 4 + 七(二) Babel 4 + 七(三) Loader/Plugin 6 + 七(三) 其他 3 个中移除 2 个(core-js 保留升级),另有后续 lodash 替换)。
构建核心(4 个)
webpack --- 打包器
原用途:Webpack 是整个构建流程的核心。它把项目中的所有资源(JS/CSS/图片/字体)视为模块,通过 loader 链串联处理,输出为浏览器可执行的 bundle。
Webpack 的核心机制:
┌──────────────┐
入口文件(entry)──→│ 模块依赖图 │──→ 输出 bundle
│ (Module │
│ Graph) │
└──────────────┘
│
┌─────┴──────┐
│ │
▼ ▼
Loader 链 Plugin 钩子
(转换文件内容) (干预构建流程)
Webpack 的核心数据结构 :ModuleGraph。Webpack 从入口文件出发,递归解析所有 import/require 语句,构建一个模块依赖图。每个模块(文件)在图中是一个节点,包含:
- 模块 ID(通常是路径)
- 模块内容(源码字符串)
- 模块依赖列表(子模块列表)
- 模块类型(JS/CSS/SVG 等)------决定走哪条 loader 链
为什么不再需要 :Vite 开发环境完全不需要打包器。Vite 开发服务器基于原生 ESM ------浏览器直接 import 源码文件,Vite 只做实时转译(esbuild)和按需编译。生产构建使用 Rollup 打包,因此 Vite 不需要 webpack 包。
"打包"这件事本身没有消失,只是换了一个工具做:开发时不需要打包(用原生 ESM),生产时用 Rollup 而非 Webpack 打包。
@vue/cli-service --- Vue CLI 服务层
原用途 :@vue/cli-service 是 Vue CLI 的核心,它封装了 Webpack 配置,提供了 vue-cli-service serve、vue-cli-service build、vue-cli-service lint 等命令。这个包做了三件事:
- 提供 Webpack 预设配置(
node_modules/@vue/cli-service/webpack.config.js) - 封装命令入口(
serve/build/lint) - 提供插件机制(
@vue/cli-plugin-*)
为什么不再需要 :Vite 本身就是 CLI,不需要再封装一层。vite 命令直接替代 vue-cli-service serve,vite build 直接替代 vue-cli-service build。
关键区别:
Vue CLI 的调用链:
vue-cli-service serve
→ 读取 @vue/cli-service 内置的 Webpack 配置
→ 合并 vue.config.js 中的自定义配置
→ 启动 Webpack Dev Server
Vite 的调用链:
vite
→ 读取 vite.config.js 配置
→ 启动 Vite Dev Server(内置 esbuild + 原生 ESM 支持)
少了"内置配置→合并→生成 Webpack 配置"这一中间层,Vite 的启动链更短、更直接。
@vue/cli-plugin-babel --- Babel 插件集成
原用途 :Vue CLI 的插件系统允许通过 @vue/cli-plugin-* 扩展功能。@vue/cli-plugin-babel 的作用是在 Vue CLI 中集成 Babel------它负责:
- 自动添加
babel-loader到 Webpack 的 JS 处理规则 - 读取
babel.config.js配置 - 在
vue-cli-service serve和vue-cli-service build中启用 Babel 转译
为什么不再需要 :Vite 使用 esbuild 做转译,不需要 Babel 链路。@vue/cli-plugin-babel 这个"集成胶水"也随之消失。
@vue/cli-plugin-eslint --- ESLint 插件集成
原用途 :在 vue-cli-service serve 启动时自动运行 ESLint,在 vue-cli-service lint 时执行 lint 修复。它把 ESLint 绑定到了 Webpack 的编译流程中------开发时文件修改后,Webpack 重新编译,ESLint 检查作为一个 loader 在编译过程中运行。
为什么不再需要 :Vite 本身不集成 ESLint。ESLint 作为独立命令运行,不绑定到 dev server 的编译流程。这是刻意的设计选择------ESLint 和构建解耦,让构建更快(不需要等 ESLint 检查完才刷新页面),ESLint 也可以通过 IDE 插件实时运行,不依赖构建工具。
迁移变化:
Webpack 时期: 修改文件 → Webpack 重新编译 → ESLint 检查 → 输出结果
(ESLint 绑在编译流程中,拖慢每次热更新)
Vite 时期: 修改文件 → Vite 即时编译 → 浏览器刷新
(ESLint 独立运行,不阻塞构建)
IDE 插件或 eslint --fix 命令单独执行
Babel 相关(4 个)
(内容见第七节(二))
附录:Webpack vs Vite vs Rollup vs esbuild 分工图
┌─────────────────────────────────────────────────────────────────┐
│ 构建工具链分工对比 │
│ │
│ Webpack 时期(开发 + 生产统一走 webpack): │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ webpack(打包器 --- JS 实现) ││
│ │ ├── 开发/生产公用:babel-loader(调用 Babel 转译 ES6→ES5)││
│ │ ├── 开发/生产公用:webpack(递归构建模块依赖图,打包) ││
│ │ ├── 仅开发:webpack-dev-server(HMR 热更新) ││
│ │ └── 仅生产:terser-webpack-plugin(调用 terser 压缩) ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ Vite 时期(开发/生产走不同路径): │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ Vite(协调者) ││
│ │ ├── 开发:不打包,浏览器直接加载源码 ESM ││
│ │ │ ├── esbuild:预构建 node_modules(CJS→ESM,仅开发) ││
│ │ │ └── 不做语法降级(target 为现代浏览器集合,原生 ES6+) ││
│ │ └── 生产:Rollup 打包 + esbuild 压缩 ││
│ │ ├── Rollup:tree-shaking + 代码分割 + 插件 ││
│ │ └── esbuild:压缩(build.minify)+ 去 console(esbuild.drop)││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ 各工具职责(按阶段): │
│ │
│ esbuild(Go)--- 仅开发 + 仅生产后半段: │
│ ├── 预构建(仅开发):node_modules 依赖 CJS→ESM、碎片合并 │
│ ├── 压缩(仅生产):替代 terser,vite.config.js build.minify │
│ ├── 去 console(仅生产):vite.config.js esbuild.drop │
│ └── ⛔ 不做 ES6→ES5 语法降级(最低 target=es2015,无 es5) │
│ │
│ Rollup(JS)--- 仅生产: │
│ ├── tree-shaking + 代码分割(manualChunks) │
│ ├── 插件系统(vite-plugin-compression / visualizer) │
│ └── 输出优化(chunk 命名 + content hash) │
│ │
│ Vite(JS)--- 贯穿开发+生产: │
│ ├── 开发服务器(原生 ESM + 按需编译,不打包) │
│ ├── 配置管理(vite.config.js 统一入口) │
│ ├── CSS 管线(PostCSS + Less → autoprefixer + additionalData)│
│ └── 生产构建委托(调用 Rollup 打包 + esbuild 压缩) │
└─────────────────────────────────────────────────────────────────┘
关键认知 :Vite 不是"替代 Webpack 的另一个打包器"------它是一个开发服务器 + 构建协调器。开发时用 esbuild 做即时转译(不打包),生产时调用 Rollup 做打包。Vite 本身不参与打包,它只是把不同阶段的工作委托给最适合的工具。
本节小结 :配置文件从 332 行减少到 200 行(约 -40%),不是因为"改小了",而是因为 Vite 不需要 Webpack 那一层封装壳 。四个构建核心包中,
webpack被 Vite + Rollup 分工替代,@vue/cli-service被viteCLI 直接替代,@vue/cli-plugin-babel和@vue/cli-plugin-eslint随 Babel/ESLint 与构建解耦而自然消失。分工图见文末。