最近我想尝试参与 Ant Design 的开源共建,于是按照熟悉的流程 fork、clone、安装依赖,再启动本地开发服务。本来以为很快就能看到页面,结果项目一直停在 Bundling,终端没有直接报错,浏览器页面也始终没有进入可用状态。
这篇文章记录一下我从反复切换环境,到最后暂时绕过问题的完整过程。先说明结论:问题与启用 UtooPack 后的监听、重启过程有关;移除 UtooPack 配置并回退到 Webpack 后,项目可以在几分钟内完成构建。 不过这只能证明问题范围,还不能直接等同于最终根因。
问题从一直不结束的 Bundling 开始
第一次启动项目时,终端没有出现常见的红色错误,但同一组日志一直在重复:配置发生变化、开发服务器重新启动,然后再次检测到变化。
图 1:终端不断出现 config metas changed, restart server...。
浏览器里的页面一直停留在 Bundling,请求中的 bundle-status 虽然能正常返回,但 done 始终是 false。
图 2:构建状态始终没有完成。
到这里我才意识到,它可能不是单纯的"首次构建比较慢"。如果只是慢,日志通常会继续向前推进;而我这里的关键特征是:开发服务在重复启动,构建进度也随之被不断重置。
这时页面里还能看到当前使用的构建工具是 UtooPack,这也成了后面继续排查的重要线索。
先排除 Node.js 和包管理器问题
遇到构建问题,我最先怀疑的还是运行环境。于是我切换过 Node.js 版本,也重新安装过依赖,前后尝试了几次,结果都一样。
我又查看了 UtooPack 的说明,它要求 Node.js 20 及以上版本,而我的环境已经满足这个条件,所以至少可以先排除"Node.js 主版本过低"这个原因。
图 3:文档中的 Node.js 版本要求。
随后我去社区群里求助,得到的建议主要有两个:
- 改用
pnpm安装依赖; - 使用 Node.js 22,并通过 Utoo 重新下载依赖。
图 4:社区里给出的排查方向。
这些建议都很合理,因为不同包管理器的依赖布局、软链接处理方式确实可能影响 monorepo 项目。我按建议重新尝试后,构建仍然会卡住。到这一步,继续反复删除 node_modules 的意义已经不大了,问题更像是发生在构建和文件监听阶段。
第一次跑通了,但问题并没有真正解决
自己排查没有进展后,我让 Codex 帮忙安装依赖并启动开发服务器。第一次尝试同样卡了十几分钟,我中途放弃了。第二次我决定让它继续处理,前后等了接近一个小时,项目终于成功启动。
图 5:等待约 54 分钟后,开发服务器终于启动。
我把进展反馈到群里,大家看到接近一小时的启动时间也很意外。对一个前端开发服务来说,这显然不能算正常结果。
图 6:项目虽然跑起来了,但耗时明显异常。
更重要的是,我回看 Codex 的处理记录后发现,这次成功依赖了不少临时操作。它证明项目不是完全无法运行,却没有给出一个可以稳定复现的启动方式。
这里有一个很容易忽略的区别:
- 偶然启动成功,只能说明环境具备运行项目的基本条件;
- 每次都能在合理时间内启动,才说明问题真正得到解决。
所以我又回到了最初那条反复出现的日志上:为什么配置会持续发生变化,导致开发服务器不断重启?
真正的线索:文件监听触发了重复重启
UtooPack 是 Utoo 工具链中的高性能构建器,底层由 Turbopack 提供能力。项目中的配置还要求它额外监听一部分 node_modules 内容:
ts
utoopack: {
watch: {
nodeModulesRegexes: ['rc-.*', '.*cssinjs.*', '@rc-component/.*'],
},
},
从配置意图看,这段代码并不奇怪。Ant Design 本地开发会涉及 rc-*、cssinjs 和 @rc-component/* 等相关依赖,监听这些包有利于开发时及时感知源码变化。
但结合我本地的日志来看,某些变化事件很可能被持续捕获,进而触发配置重新生成和开发服务重启。每次重启都会中断当前构建,于是页面看起来一直在 Bundling,实际上是在重复从头开始。
需要强调的是,我当时没有继续追踪"究竟是哪一个文件在变化",所以暂时无法判断它属于 UtooPack 本身的问题、Windows 文件监听差异,还是依赖目录结构与当前配置共同触发的边界情况。这里能确认的是:异常发生在启用这段 UtooPack 配置之后,并且移除配置后不再出现。
临时方案:回退到 Webpack
为了先恢复正常开发,我删除了上面的整个 utoopack 配置块,再重新启动项目。
从后面的终端输出看,项目实际上不再使用 UtooPack,而是回退到了 Webpack。
重新启动后,页面终于出现了持续增长的构建进度,而不是一直停在没有结果的状态。

图 7:构建进度开始正常推进。
几分钟后,终端出现了 [Webpack] compiled,项目顺利完成构建。这次的速度才符合我对本地开发服务的预期。
图 8:回退到 Webpack 后构建成功。
这次排查给我的几个提醒
这次问题不算彻底查到底,但排查过程里有几条经验还挺值得记录。
没有报错,不代表程序运行正常
终端一直有新日志,很容易让人误以为构建只是比较慢。但如果同一组"检测变化、重新启动"日志持续重复,就应该先判断流程是否陷入循环,而不是继续等待。
先区分构建慢,还是构建被反复重置
构建慢时,模块数、依赖数或页面进度通常还在增长;构建被重置时,状态会回到起点,服务端也会反复初始化。这两种现象需要完全不同的排查方向。
环境检查要做,但不要只会重装依赖
确认 Node.js 版本、包管理器和锁文件当然有必要。不过一旦这些条件已经满足,而且问题可以稳定复现,就应该继续观察日志、网络请求和构建器配置。反复删除 node_modules 往往只是增加等待时间。
绕过问题和找到根因是两件事
回退到 Webpack 解决了"项目无法正常启动"的直接问题,但还没有回答 UtooPack 为什么会在我的环境里反复重启。
最后
所以,为什么我本地构建 Ant Design 一直不成功?目前看来是:项目中启用 UtooPack 监听配置后,我的本地开发服务陷入了重复重启;移除配置、回退到 Webpack 后,构建恢复正常。
这次经历也提醒我,排查构建问题时不能只盯着最后有没有报错。重复日志、一直为 false 的状态接口,以及构建工具的切换,往往比一条显眼的错误信息更接近答案。
至于触发 UtooPack 重启的底层原因,等后面真正定位到具体文件和复现条件后,再单独补一篇后续。