Webpack迁到Vite第七节(四):全家桶移除 — 保留项、脚本与数据收尾

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 时(注意:没有 -- 分隔符):

  1. npm 把 --brand_color=#DC143C 当作 npm 自身的配置参数
  2. npm 设置环境变量 npm_config_brand_color=#DC143C
  3. npm 执行 serve 脚本(即 vite)
  4. 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 命令做了什么额外的事情? 它实际上做了三件事:

  1. 调用 ESLint API 检查代码
  2. 如果 lint 失败,阻止 Webpack 编译(开发环境)
  3. 在 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 文件是否存在 → 存在 → 通过

为什么移除后还能正常工作

两个原因:

  1. Webpack 配置文件不存在了 :node_modules/@vue/cli-service/webpack.config.js 在移除 @vue/cli-service 后已经不存在,这个配置指向了一个不存在的文件。

  2. 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%。这是因为:

  1. 净少装 8 个包(及其传递依赖),依赖树更浅
  2. 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 是测试依赖------没有一个是为了保留而保留。

相关推荐
LuHang19 分钟前
我一行代码没写,把领导派的活做成了公司内部系统😭
前端
明月_清风26 分钟前
Meta 开源了一个 AI Native 组件库:Astryx,150+ React 组件,专为 AI Agent 而设计
前端·人工智能·ai编程
用户0873086548742 分钟前
用 GUI 自动化写了一个群聊 AI:5 个真实事故,和 7 条让 AI 不像机器人的设计
node.js
用户850869276151 小时前
秒杀系统中 Shell 脚本并发控制 Bug:究竟哪里出了
前端
炫酷的大高个3 小时前
6 亿播放的闪身步,我用前端算出 15 倍重心差
前端·javascript
不可能片场3 小时前
内容运营自动化 配图折行别把词切两半
前端·electron
Lank_M4 小时前
HEIC转JPG统一转sRGB,P3高饱和色就回不来了
前端
补码缩写4 小时前
sharp默认转JPG颜色没错,ICC和EXIF却全没了
前端
用户7783366132114 小时前
SerpBase AI Overview 引用卡片:React 组件实战
前端
林小帅4 小时前
【笔记】Prisma v7 + SQLite TS2305 及连锁 TS7006 问题
前端·javascript·后端