构建工具的一些思考:一个北漂(伪)程序员的深夜碎碎念

事件循环乘客
2025-12-17 10:41
阅读 469

上周五晚上十点半,我正戴着 AirPods 听着 Lofi Girl 的 beat 写代码,突然收到测试群里@全体成员的消息:“线上静态资源加载超时了,用户投诉页面白屏!”——那一刻,我真的想把 MacBook 直接从窗户扔出去。房贷还没还完,项目却在搞我。

虽然我现在人在成都,过着“慢节奏”的伪北漂生活(其实是被高房租劝退后逃回来的),但工作强度一点没少。我们团队最近在搞一个 AI 驱动的运营中台,产品经理天天催“要快!要轻!要能秒开!”,结果构建脚本一跑就是 5 分钟,上线前还得祈祷别出错。于是,我被迫重新审视起那些被我们当成“黑盒”用的构建工具——Webpack、Vite、Rollup、甚至 Turbopack……它们到底是救星,还是背锅侠?

被逼上梁山:为什么又得折腾构建?

事情起源于上个月的一次性能复盘会。运维甩出一组数据:我们的管理后台首屏加载时间平均 4.8s,在弱网下直接飙到 8s+。老板一听就急了:“这体验怎么搞运营?用户都跑了!”——对,你没看错,运营成了压垮骆驼的最后一根稻草。

更扎心的是,我朋友上周跳槽面试,被问:“你们项目的构建流程是怎么优化的?”他支支吾吾说“用了 Webpack splitChunks”,结果面试官反问:“那你知道 splitChunks 的 cacheGroups 是怎么影响长期缓存的吗?”他当场懵了。回来跟我吐槽:“现在连面试题都卷到构建工具了?”

我苦笑:可不是嘛。以前觉得构建工具就是配个 config,跑通就行。现在发现,它直接决定了你的 bundle 大小、加载速度、缓存策略,甚至影响 SEO 和转化率——对,就是那个和运营强相关的指标。

Webpack:老将不死,只是臃肿

我们主项目还在用 Webpack 5。不是不想换,是不敢换。毕竟几十个页面、上百个模块,重构成本太高。但它的慢是真的肉眼可见:

  • 开发模式热更新经常卡 10s+
  • 生产构建时内存爆到 4GB
  • 某次不小心把 node_modules 打包进 vendor,上线后 CDN 费用翻倍(财务找我谈话时我差点跪下)

后来我花了一周时间做优化,核心思路就两个字:

// webpack.config.js 片段
optimization: {
  splitChunks: {
    chunks: 'all',
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all',
        enforce: true,
        priority: 10
      },
      // 关键:按业务模块拆分
      dashboard: {
        test: /[\\/]src[\\/]pages[\\/]dashboard/,
        name: 'dashboard',
        chunks: 'all',
        enforce: true
      }
    }
  },
  runtimeChunk: 'single'
}

加上 hard-source-webpack-plugin 做持久化缓存后,二次构建时间从 210s 降到 68s。虽然还是慢,但至少不用每次喝完一杯咖啡才能看到改动效果了。

不过说实话,Webpack 的配置就像写散文——自由但容易跑偏。有一次我把 minimize 关了调试,忘了打开,上线后 bundle 大了 3 倍,被运维追着骂了三天。

Vite:真香,但别盲目上头

新搞的 AI 实验项目,我果断上了 Vite。启动速度飞快,HMR 基本无感,ESBuild + Rollup 的组合拳打得漂亮。但你以为这就完了?Too young。

问题出在兼容性上。我们有些老组件用了 CommonJS 模块,Vite 默认不支持。结果本地跑得好好的,CI 流水线一跑就报错:

[vite] error during build:
Error: 'default' is not exported by node_modules/old-lib/index.js

查了半天才发现得加 vite-plugin-commonjs。更坑的是,某些动态 import() 语法在生产构建时会被 Rollup 静态分析搞乱路径,导致懒加载失败——用户点“数据分析”按钮,页面直接 404。

所以我的建议是:新项目可以冲 Vite,老项目迁移务必谨慎。别被“快”字蒙蔽了双眼,生态兼容性才是深水炸弹。

性能对比:数字不会骗人

为了说服团队 leader 支持我重构构建流程,我做了个简单 benchmark(基于同一套 React + Ant Design 代码):

工具 开发启动时间 HMR 更新时间 生产构建时间 Bundle 大小 (gzip)
Webpack 5 8.2s 3.1s 124s 1.8MB
Vite 4 0.4s 0.1s 28s 1.6MB
Turbopack (alpha) 0.3s 0.05s N/A (dev only) -

注:Turbopack 目前仅支持开发环境,且对 Next.js 以外框架支持有限。

看到 Vite 的构建时间只有 Webpack 的 1/4,leader 终于点头让我试点。不过他也补了句:“别整崩了,下周双11大促,崩了你赔运营损失。”

构建优化 ≠ 工具替换

很多人以为换工具就能解决问题,其实不然。我在优化过程中踩过几个经典坑:

  1. 过度拆包:一开始我把每个 npm 包都单独拆成 chunk,结果 HTTP 请求从 5 个变成 50 个,首屏反而更慢了(TCP 连接开销太大)
  2. 忽略缓存策略:没配好 contenthash,导致用户每次刷新都要重新下载所有 JS,CDN 缓存形同虚设
  3. 开发体验牺牲太多:为了极致压缩,关掉 sourceMap,结果线上报错根本没法 debug

真正的优化,应该围绕业务场景展开。比如我们的运营后台,90% 用户只用 3 个核心功能,那我就把其他模块全做成动态 import,首屏 bundle 直接砍掉 40%。

// 动态导入非核心模块
const ReportPage = lazy(() => import('@/pages/Report'));
const SettingsPage = lazy(() => import('@/pages/Settings'));

配合 webpackPrefetch 提前加载,用户体验几乎无损。

最后一点真心话

作为一个月供 7k 的“伪北漂”,我其实挺怕折腾这些底层东西的——万一搞砸了,绩效扣了,房贷咋办?但现实是,构建工具已经不再是“基建”,而是直接影响产品成败的关键环节

现在每次写代码,我都会多问一句:这个依赖真的必要吗?这个功能值得放在首屏吗?能不能用原生 ES 模块替代?……这种“斤斤计较”,可能就是被房贷逼出来的职业素养吧(笑)。

如果你也在被构建速度折磨,或者正在准备面试被问到这类面试题,不妨从一个小模块开始优化。别想着一口吃成胖子,先让 bundle 小 100KB,再让构建快 10 秒——积少成多,总比线上事故后背锅强。

对了,昨晚那个白屏问题,最后定位到是 CDN 配置错了 Cache-Control,和构建工具无关……但这段排查经历,又让我对整个交付链路有了更深的理解。果然,程序员的成长,都是用 bug 堆出来的。

(写完这篇,房贷还款日又近了一天。算了,继续听歌写代码吧。)

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝