Webpack迁到Vite第七节(四):全家桶移除 --- 保留项、脚本与数据收尾
本篇定位 :依赖从 48 个精简到 40 个(共移除 17 个、新增 9 个,净减 8 个)------留下的每个都有留下的理由。本篇梳理保留原因、脚本命令的对应关系、
.eslintrc.js清理了什么,以及最终的依赖数量、构建时间、配置文件体积的对比数据。
思维导图
保留项、脚本与数据收尾
├── 1.3 保留的依赖包(23 个)--- 为什么这些包没有被移除
│ ├── less + autoprefixer(Less 编译器 + CSS 前缀)
│ ├── browserslist(共享给 autoprefixer + plugin-legacy)
│ ├── vue-template-compiler(仅 @vue/test-utils 需要)
│ └── eslint + 插件链 + 测试工具链
├── 1.4 脚本命令更新
│ ├── 原则:核心脚本名不变(serve/build/lint)
│ ├── serve / serve:params / build / build:params / analyze
│ ├── lint / lint:fix(独立于构建工具)
│ └── 测试脚本(vitest + Playwright,迁移前已配置)
├── 1.5 .eslintrc.js 清理
│ ├── import/resolver webpack → custom-alias
│ └── import/extensions: off(Vue 生态惯例)
├── 1.6 依赖数量对比
│ ├── 48 → 40(净减 8 个包)
│ ├── 配置文件:332 → 200 行(约 -40%)
│ ├── 构建时间:3m31s → 37s(-82%)
│ └── npm install:70s → 15s(-79%)
└── 总结
1.3 保留的依赖包(23 个)
为什么这些包被保留
| 包名 | 保留原因 | 详细说明 |
|---|---|---|
vite |
新的构建工具 | 替代 Webpack + @vue/cli-service |
@vitejs/plugin-vue2 |
Vue 2 SFC 编译 | Vite 需要这个插件来解析 .vue 文件 |
@vitejs/plugin-legacy |
ES5 降级双构建 | 为旧浏览器额外产出 nomodule 传统产物(详见第七节(五)) |
vite-plugin-compression |
.gz 预压缩 | 替代 compression-webpack-plugin |
rollup-plugin-visualizer |
构建分析 | 替代 webpack-bundle-analyzer |
vitest |
单元测试 | 独立测试框架,与构建工具无关 |
@vitest/coverage-v8 |
测试覆盖率 | vitest 的覆盖率插件 |
@playwright/test |
E2E 测试 | 独立测试框架,与构建工具无关 |
@vue/test-utils |
Vue 组件测试 | 测试 Vue 组件的工具库 |
jsdom |
测试 DOM 环境 | vitest 的 DOM 模拟环境 |
eslint |
代码检查 | 独立于构建工具 |
eslint-plugin-vue |
Vue 规则 | ESLint 的 Vue 语法规则 |
eslint-plugin-import |
Import 规则 | ESLint 的 import 规则 |
@vue/eslint-config-airbnb |
Airbnb 规则预设 | ESLint 规则集 |
eslint-import-resolver-custom-alias |
ESLint import 别名解析 | 替代 eslint-import-resolver-webpack,解析 @/ 别名和 .vue 扩展名 |
less |
CSS 预处理器 | 编译器本身,Vite 不内置 |
autoprefixer |
CSS 浏览器前缀 | Vite 内置 PostCSS,但 autoprefixer 需要单独安装 |
vue-template-compiler |
模板编译 | vitest 需要(Vite 构建时由 @vitejs/plugin-vue2 处理) |
core-js |
保留(^3.38.1 → ^3.50.0 升级) | 迁移前已有,迁移后升级;供 plugin-legacy 传统构建注入 polyfill |
regenerator-runtime |
async/await 运行时 | 配合 @vitejs/plugin-legacy 为传统构建提供 regenerator 运行时 |
terser |
传统产物压缩 | plugin-legacy 产出的 legacy chunk 由 terser 压缩(esbuild 不做 ES5 降级) |
ioredis |
测试 Redis 查询 | 测试辅助工具,与构建工具无关 |
mysql2 |
测试数据库查询 | 测试辅助工具,与构建工具无关 |
关键保留项说明
less + autoprefixer 为什么保留?
less :Vite 内置了 Less 集成层(调用的胶水代码),但不是"编译器"本身。less 包是 Less 语言的编译器,负责把 Less 语法解析并编译为 CSS。Vite 没有重写这个编译器。
autoprefixer:完整的工具链分工如下:
Vite(构建工具)
└── 内置 PostCSS 集成(自动检测 postcss.config.js)
└── postcss.config.js → plugins: { autoprefixer: {} }
└── autoprefixer(npm 包,需单独安装)
└── 读取 browserslist 配置,确定要加哪些 CSS 前缀
Vite 内置了 PostCSS 的"集成管道"------自动检测项目中的 postcss.config.js,把它接入构建流程。但 PostCSS 的具体插件(如 autoprefixer)需要自己安装------Vite 只负责管道,不打包插件。
browserslist 为什么保留?
browserslist 从 package.json 中保留,原因是它仍然是两个独立消费方的共享配置:
| 消费者 | 用途 | 是否还在用 |
|---|---|---|
| Babel(Webpack 时代) | @babel/preset-env 根据它确定需要降级哪些 ES6+ 语法 |
❌ 已移除 |
autoprefixer |
根据它确定要为哪些浏览器添加 CSS 前缀(-webkit- 等) |
✅ 仍在使用 |
@vitejs/plugin-legacy |
H5 签署端 ES5 降级,plugin-legacy 依赖它确定传统构建的转译目标 |
✅ 已实施(详见第七节(五)) |
Babel 移除不意味着 browserslist 应该删除------它从来不是 Babel 独占的配置。autoprefixer 通过 postcss.config.js 接入 Vite 的 PostCSS 管线,读取 browserslist 生成 CSS 前缀。@vitejs/plugin-legacy 同样依赖它确定传统构建的转译目标。
完整链路:
postcss.config.js → autoprefixer → browserslist → CSS 前缀 ← 现在
@vitejs/plugin-legacy → Babel → browserslist → ES5 语法降级 ← 已实施(见第七节(五))
package.json 中的最终配置(与 Webpack 时期一致):
json
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
]
不删除的另一个原因是可控性:browserslist 默认值会随 npm 包版本升级而变化,显式声明锁定项目意图,避免某天默认值改变导致构建产物意外变化。
vue-template-compiler 为什么保留?
vue-template-compiler 只有一个消费者:@vue/test-utils@1.3.6。
vitest(测试运行器)
→ 加载测试文件
→ mount(Component) ← @vue/test-utils
→ require('vue-template-compiler').compileToFunctions()
→ 将 Vue 模板编译为 render 函数
源码验证 (node_modules/@vue/test-utils/dist/vue-test-utils.js):
javascript
var vueTemplateCompiler = require('vue-template-compiler');
var el = vueTemplateCompiler.compileToFunctions(
"<div><template slot=" + name + ">" + slotValue + "</template></div>"
);
@vue/test-utils 在 mount 组件时需要将模板字符串编译为 render 函数------这是 Vue 2 特有的步骤(Vue 3 的 @vue/test-utils 不再需要)。@vue/test-utils 将其声明为 peerDependency,由消费项目提供。
与 @vitejs/plugin-vue2 无关 :@vitejs/plugin-vue2 的 peerDeps 只有 vite 和 vue,不依赖 vue-template-compiler------它使用自己的内部编译器处理 .vue 文件。生产构建不需要 vue-template-compiler。
结论 :保留它的唯一原因是 @vue/test-utils 需要。如果项目不使用 @vue/test-utils(或升级到 Vue 3),就可以移除。
1.4 脚本命令更新
原则:核心脚本名不变
脚本名是 CI/CD 流水线、Dockerfile、开发文档中的硬编码引用。迁移策略是:核心脚本名(serve/build/lint)保持不变,只替换内部调用的命令 。带参数的辅助脚本在后续优化中统一为 :params 命名风格(如 serveStart → serve:params)。
逐命令分析
npm run serve:vite
json
"serve": "vite"
为什么叫 serve 而不是 dev? 这是直接从 Vue CLI 时期继承的命名。Vue CLI 使用 vue-cli-service serve 启动开发服务器,所以脚本名叫 serve。保持这个命名,CI/CD 中写 npm run serve 的地方不需要改。
vite 命令不带参数时,默认启动开发服务器,默认端口 5173(本项目在 vite.config.js 中配置为 8080 ,并开启 host: true 与 strictPort: false------详见第九节 §1.5)。
npm run serve:params:npm run serve --brand_color=#DC143C --custom_path=/privatiza20 --tag_name=
json
"serve:params": "npm run serve --brand_color=#DC143C --custom_path=/privatiza20 --tag_name="
(迁移初期名为 serveStart,后续统一为 :params 命名风格。)
npm_config_ 机制详解:
当执行 npm run serve --brand_color=#DC143C 时(注意:没有 -- 分隔符):
- npm 把
--brand_color=#DC143C当作 npm 自身的配置参数 - npm 设置环境变量
npm_config_brand_color=#DC143C - npm 执行
serve脚本(即vite) vite.config.js中process.env.npm_config_brand_color读取到'#DC143C'
关键区分------npm 的两种参数传递方式(实测验证):
方式 A: npm run serve --brand_color=#DC143C ← 项目实际用法
→ npm 解析 --brand_color → 设置 npm_config_brand_color 环境变量 → ✅
方式 B: npm run serve -- --port 8080 ← 传给 vite 的 CLI 参数
→ -- 后面的是给脚本的 → node/vite 的 process.argv 接收 → 不设环境变量
# 为什么安全? 实测 npm run env-test --brand_color=#DC143C:npm 在 shell 解释之前解析参数,#DC143C 完整保留,不会触发 shell 的注释行为。如果直接写 vite --brand_color=#DC143C(不通过 npm),bash 会把 # 后的内容当作注释截断。
npm run build:vite build
json
"build": "vite build"
vite build 使用 Rollup 执行生产构建。默认输出到 dist/ 目录,产物经过代码分割、压缩、css 提取等处理。
相比 vue-cli-service build --no-module:
Webpack 时代使用 --no-module 是因为构建产物是 ES5,用普通 <script> 标签加载,所有浏览器都能执行。Vite 的构建产物是 ESM,必须用 <script type="module"> 加载:
html
<!-- Webpack 产物(ES5) -->
<script src="/js/chunk-vendors.js"></script> ← 所有浏览器都能加载
<!-- Vite 产物(ESM) -->
<script type="module" src="/assets/index-abc.js"></script> ← 仅现代浏览器能加载
<script type="module"> 在 HTML 规范中的行为:
| 浏览器 | 行为 | 结果 |
|---|---|---|
| 支持 ESM(Chrome 61+) | 正常下载、解析、执行 | ✅ |
| 不支持 ESM(IE11、旧 Android WebView) | 静默跳过此标签,不下载不报错 | ❌ 白屏 |
这是 HTML 规范的刻意设计------不支持的浏览器不会尝试降级,直接忽略。Vite 默认只生成 <script type="module">,没有 <script nomodule> 兜底。这意味着旧浏览器用户看到的将是空白页面------与 Webpack 时代的 ES5 bundle 兼容性存在本质差异。
这正是 @vitejs/plugin-legacy 解决的问题(详见 第七节(五):ES5 降级方案专题):双构建后同时输出现代产物(type="module")和传统产物(nomodule),旧浏览器通过 <script nomodule> 加载 ES5 版本。
npm run analyze:npm run build --report
json
"analyze": "npm run build --report"
--report 参数通过 npm_config_report 环境变量传递给 vite.config.js。vite.config.js 中判断 process.env.npm_config_report 是否存在,若存在则启用 rollup-plugin-visualizer:
javascript
// vite.config.js 的 visualizer 条件插件
...(process.env.npm_config_report ? [visualizer({...})] : []),
注意 :npm run build --report 会用 --report 参数调用 vite build,但 vite build 本身不认识 --report。关键在于 npm 把 --report 转换为 npm_config_report 环境变量,vite.config.js 读取的是这个环境变量,不是 CLI 参数。
npm run build:params:带参数的构建
json
"build:params": "npm run build --brand_color=#DC143C --custom_path=/privatiza20 --tag_name=v4.3.0"
--tag_name=v4.3.0 通过 npm_config_tag_name 传递给 vite.config.js,最终注入到 import.meta.env.APP_TAGNAME 编译时常量中。
为什么 tag_name、brand_color、custom_path 同时出现? 项目构建时,版本标识(tag)、品牌色和部署路径是独立配置的。build:params 在同一个脚本中组合这三个参数,覆盖实际部署时的完整需求。(迁移初期名为 build:tagName,参数仅有 --tag_name=我是好人,后续统一为 :params 命名风格并补齐参数。)
npm run lint:fix:eslint --ext .js,.vue src --fix
json
"lint": "eslint --ext .js,.vue src",
"lint:fix": "eslint --ext .js,.vue src --fix"
逐参数拆解:
| 参数 | 值 | 作用 |
|---|---|---|
--ext |
.js,.vue |
指定检查的文件扩展名。逗号分隔多个扩展名,ESLint 只检查匹配这些扩展名的文件 |
src |
src |
指定检查目录。ESLint 递归扫描 src/ 下所有匹配 --ext 的文件 |
--fix |
--- | 自动修复可修复的问题(如缩进、分号、引号风格等)。不可修复的问题(如逻辑错误)只报告不修复 |
为什么从 vue-cli-service lint --fix 改为 eslint --ext .js,.vue src --fix?
vue-cli-service lint 是 @vue/cli-plugin-eslint 提供的命令,它封装了 ESLint 的调用。移除 Vue CLI 后,直接使用 eslint 命令。
@vue/cli-plugin-eslint 的 lint 命令做了什么额外的事情? 它实际上做了三件事:
- 调用 ESLint API 检查代码
- 如果 lint 失败,阻止 Webpack 编译(开发环境)
- 在
vue-cli-service build时,lint 错误会阻止构建
Vite 不集成 ESLint,所以这些"阻止构建"的行为不再需要。ESLint 作为独立工具运行,不影响构建流程。
lint vs lint:fix 的区别 :lint 只检查不修复(用于 CI 流水线),lint:fix 检查并自动修复(用于本地开发)。两者共用同一套参数,只是 --fix 的有无。
测试脚本(迁移前已配置,保留不变)
以下 6 个测试脚本自 2026-08-13 起已配置,迁移过程中保留不变:
json
"test": "vitest run",
"test:watch": "vitest",
"test:e2e": "playwright test",
"test:e2e:headed": "playwright test --headed",
"test:e2e:ui": "playwright test --ui",
"test:coverage": "vitest run --coverage"
| 脚本 | 命令 | 作用 |
|---|---|---|
test |
vitest run |
运行单元测试(单次,不监听) |
test:watch |
vitest |
运行单元测试(监听模式,文件变更自动重跑) |
test:e2e |
playwright test |
运行 E2E 测试(无头浏览器) |
test:e2e:headed |
playwright test --headed |
运行 E2E 测试(有头浏览器,弹出可见窗口查看页面实际操作) |
test:e2e:ui |
playwright test --ui |
打开 Playwright 交互式测试面板,可浏览用例列表、按需重跑、开启时间旅行调试 |
test:coverage |
vitest run --coverage |
运行单元测试并生成覆盖率报告 |
--headed vs --ui 的区别:
--headed |
--ui |
|
|---|---|---|
| 本质 | 让浏览器窗口可见 | Playwright 交互式测试面板 |
| 浏览器窗口 | 弹出可见窗口 | 默认 headless(可在面板中手动切换) |
| 交互性 | 无,跑完即结束 | 有------点击重跑、查看 Trace、按用例筛选 |
| 适用场景 | 调试某个测试,想看页面实际操作 | 开发阶段持续跑测试、浏览用例列表、复盘失败 |
--headed 只是把浏览器露出来------和执行普通命令的唯一区别是"能看到画面"。--ui 打开的是 VS Code 风格的完整测试管理面板,是开发阶段的主力工具。
为什么是 vitest + Playwright 这套组合? 迁移过程本身需要验证------每次改动后需要运行测试确认没有回归。vitest 与 Vite 共享同一套配置(vite.config.js 中的 resolve.alias、css.preprocessorOptions 等),无需额外配置测试环境。Playwright 则独立于构建工具,通过 @playwright/test 包提供。
1.5 .eslintrc.js 清理
移除的配置
原 settings['import/resolver'] 中配置的是 webpack resolver,指向已不存在的 @vue/cli-service 配置文件。该 resolver 已替换为 custom-alias(见下文"为什么移除后还能正常工作"):
javascript
// .eslintrc.js --- webpack resolver(已移除,替换为 custom-alias)
settings: {
'import/resolver': {
webpack: { // ← 这个 resolver 被移除
config: 'node_modules/@vue/cli-service/webpack.config.js'
}
}
}
当前 .eslintrc.js 中 settings 块保留,内容改为:
javascript
settings: {
'import/resolver': {
'custom-alias': { // ← 替换为 custom-alias
alias: { '@': './src' },
extensions: ['.js', '.vue', '.json', '.less', '.png', '.svg'],
},
},
},
逐行拆解:
settings :ESLint 配置中的顶层键,用于给插件传递共享配置。与 rules(控制规则开关)不同,settings 是给插件内部使用的数据,不直接影响 lint 规则。
'import/resolver' :eslint-plugin-import 的配置项。import/ 前缀表示这是 eslint-plugin-import 插件的专属配置。resolver 告诉插件"如何解析 import 路径"。
webpack :指定使用 eslint-import-resolver-webpack 这个 resolver。ESLint 插件系统支持多种 resolver------node(默认,只解析 node_modules)、webpack(读取 webpack 配置解析别名)、typescript(读取 tsconfig 解析路径映射)等。
config: 'node_modules/@vue/cli-service/webpack.config.js' :指定 webpack 配置文件的路径。resolver 会读取这个文件,从中提取 resolve.alias 配置,从而理解 @/ → src/ 的映射。
完整工作流程:
ESLint 检查 import 语句时:
import { getList } from '@/api/user'
↑
路径别名 @/ 需要解析
① 检查 settings['import/resolver']
② 发现配置了 webpack resolver
③ 读取 node_modules/@vue/cli-service/webpack.config.js
④ 找到 resolve.alias: { '@': 'src/' }
⑤ 把 @/api/user 解析为 src/api/user
⑥ 检查 src/api/user 文件是否存在 → 存在 → 通过
为什么移除后还能正常工作
两个原因:
-
Webpack 配置文件不存在了 :
node_modules/@vue/cli-service/webpack.config.js在移除@vue/cli-service后已经不存在,这个配置指向了一个不存在的文件。 -
eslint-import-resolver-custom-alias替代 :通过alias: { '@': './src' }和extensions: ['.js', '.vue', ...]配置,提供@/别名和.vue扩展名解析,使import/no-unresolved规则恢复到正常工作状态。
为什么 import/extensions: 'off' 必须保持
.eslintrc.js 中 'import/extensions': 'off' 关闭了一条规则。Airbnb 默认对其是启用的:
javascript
// eslint-config-airbnb-base 的默认配置
"import/extensions": ["error", "ignorePackages", {
"js": "never", // import .js 文件时禁止写 .js 后缀
"mjs": "never",
"jsx": "never",
}]
这条规则的含义:
| 场景 | 规则行为 | 示例 |
|---|---|---|
.js/.jsx 文件 |
禁止写扩展名 | import util from './util' ✅ / import util from './util.js' ❌ |
npm 包(ignorePackages) |
不检查 | import Vue from 'vue' ✅ |
未列出的扩展名(含 .vue) |
要求必须写 | import X from './X' ❌ 必须写成 import X from './X.vue' |
如果开启,项目中所有不带 .vue 后缀的 import 全部报错:
import CanvasSignature from './CanvasSignature' ❌ Missing file extension "vue"
import SealCard from './sealCard' ❌ Missing file extension "vue"
Vue 社区的约定俗成是 从来不写 .vue 后缀 ------这不是项目的个别选择,而是整个 Vue 生态的惯例。Airbnb 规则不了解 .vue 的存在,eslint-plugin-vue 也不处理 import/extensions。因此在 Vue 项目中这条规则必须 'off'------与 Webpack 迁移到 Vite 无关,在 Webpack 时期就应该关闭。
1.6 依赖数量对比
精确对比
迁移前(Webpack 时期):
| 分类 | 包名 | 数量 |
|---|---|---|
| 构建核心 | webpack, @vue/cli-service, @vue/cli-plugin-babel, @vue/cli-plugin-eslint |
4 |
| Babel 相关 | @babel/core, @babel/preset-env, @babel/plugin-transform-runtime, babel-plugin-import |
4 |
| Loader/Plugin | less-loader, style-resources-loader, svg-sprite-loader, compression-webpack-plugin, copy-webpack-plugin, git-revision-webpack-plugin |
6 |
| 其他 | webpack-bundle-analyzer, eslint-import-resolver-webpack |
2 |
| 后续替换 | lodash → lodash-es(1 换 1,迁移后独立提交) |
1 |
| 保留 | 所有保留的 31 个包(含 core-js,保留项:^3.38.1 → ^3.50.0 升级) |
31 |
| 总计 | 48 |
迁移后(Vite 时期):
| 分类 | 包名 | 数量 |
|---|---|---|
| 构建工具 | vite, @vitejs/plugin-vue2, vite-plugin-compression, rollup-plugin-visualizer |
4 |
| ES5 降级 | @vitejs/plugin-legacy, core-js, regenerator-runtime, terser |
4 |
| 测试 | vitest, @vitest/coverage-v8, @playwright/test, @vue/test-utils, jsdom |
5 |
| Lint | eslint, eslint-plugin-vue, eslint-plugin-import, @vue/eslint-config-airbnb, eslint-import-resolver-custom-alias |
5 |
| 样式 | less, autoprefixer |
2 |
| 编译 | vue-template-compiler |
1 |
| 辅助 | ioredis, mysql2 |
2 |
| 运行时依赖 | vue, vuex, axios 等 17 个(迁移前后不变;lodash-es 替换 lodash) |
17 |
| 总计 | 40 |
对比:48 → 40。共移除 17 个、新增 9 个,净减 8 个(迁移提交移除 16 个 + 后续 lodash → lodash-es 1 换 1 替换)。
配置文件体积对比
| 文件 | 迁移前 | 迁移后 | 减少 |
|---|---|---|---|
| 构建配置 | vue.config.js 310 行 |
vite.config.js 200 行 |
35% |
| 转译配置 | babel.config.js 22 行 |
无 | 100% |
| 合计 | 332 行 | 200 行 | 约 40% |
这些减少意味着什么
npm install 时间 (--prefer-offline,实测):Webpack 项目 ~70s,Vite 项目 ~15s,减少 79%。这是因为:
- 净少装 8 个包(及其传递依赖),依赖树更浅
- Vite 生态的包体积更小(esbuild 是 Go 写的,发布为原生二进制文件,没有 JS 依赖链)
node_modules 体积 :估计减少 40-50%。Babel 及其插件生态(@babel/core、@babel/preset-env、@babel/plugin-transform-runtime 等)的传递依赖非常多,仅 @babel/core 就有 20+ 个传递依赖。移除 Babel 后,node_modules 中减少约 100+ 个文件。
构建速度(3 轮实测平均值):
| Webpack(优化项目) | Vite(当前项目) | |
|---|---|---|
| 第 1 轮 | 3m 37s | 35s |
| 第 2 轮 | 3m 24s | 38s |
| 第 3 轮 | 3m 31s | 38s |
| 平均 | ~3m 31s (211s) | ~37s |
Vite 构建速度快约 5.7 倍(减少 82%)。差距远超"esbuild 比 Babel 快 10-20 倍"所能解释的范围------Webpack 的大部分时间消耗在模块依赖图构建和打包上(JS 实现),而 Vite 开发模式根本不打包,生产模式的 Rollup 打包效率也远高于 Webpack。
总结
| 维度 | Webpack 时期 | Vite 时期 |
|---|---|---|
| 配置文件 | vue.config.js(310行) + babel.config.js(22行) |
vite.config.js(197行) |
| 构建核心 | webpack + 80+ 个 loader/plugin | Vite + esbuild + Rollup |
| 转译 | Babel(JS 实现,慢) | esbuild(Go 实现,快 10-20 倍) |
| 打包 | Webpack(JS 实现) | Rollup(JS 实现,tree-shaking 更优) |
| 压缩 | terser(JS 实现) | esbuild(Go 实现) |
| CSS 变量注入 | style-resources-loader | additionalData |
| SVG 图标 | svg-sprite-loader | virtual module 插件(virtual:svg-icons) |
| 文件复制 | copy-webpack-plugin | configureServer + closeBundle 钩子 |
| Git 版本 | git-revision-webpack-plugin | execSync('git rev-parse') |
| 构建分析 | webpack-bundle-analyzer | rollup-plugin-visualizer |
| 依赖数量 | 48 个 | 40 个 |
| 构建时间 | ~3m 31s | ~37s |
| npm install | ~70s | ~15s |
核心代价 :去掉了手动子路径导入的样式按需加载能力,改为 antd.less 全量样式文件替代。但 Rollup 的 tree-shaking 对 JS 代码的处理效果与子路径导入一致(实验验证 bundle 大小几乎相同)。eslint-import-resolver-webpack 替换为 eslint-import-resolver-custom-alias(已安装),通过 alias 和 extensions 配置恢复了 import/no-unresolved 的完整功能。
核心理念 :Vite 的设计哲学是"内置常见功能,减少配置"。共移除 17 个包、新增 9 个(净减 8 个)------不是因为它们的功能消失了,而是因为 Vite 把这些功能内置到了自己的代码中,或者用更简单的方式(execSync、additionalData、closeBundle 钩子)替代了。
本节小结 :迁移的核心指标------依赖 48 → 40(净减 8),配置文件 332 → 200 行(约 -40%),构建 3m31s → 37s(-82%),npm install 70s → 15s(-79%)。代码量减少靠的是"壳"的消除(
vue.config.js不再是 Webpack 配置的中间层),速度提升靠的是"活"的减少(目标浏览器升级消除了转译需求)。保留的 23 个包各有各的理由------less 编译器是必需品、autoprefixer + browserslist 是共享配置、vue-template-compiler 是测试依赖------没有一个是为了保留而保留。