CommonJS 迁移 ES Module,最容易卡住的不是语法而是边界
· 阅读需 2 分钟
表面上看,CommonJS 迁移到 ES Module 很像一次语法替换:require 换成 import,module.exports 换成 export。可 2019 年前后我自己在项目里碰这件事时,真正拖慢进度的从来不是语法本身,而是模块边界和运行上下文没先想明白。
语法只是表层,边界才是难点。
哪些边界最容易先出问题
我遇到过最常见的几类卡点:
- 默认导出和具名导出在不同工具链下互操作不稳定
- Node 运行时和打包后的浏览器产物对模块格式期待不同
- 同一个目录里一半是 CommonJS,一半是 ESM,依赖方向开始混乱
- 工具脚本、构建脚本、业务代码采用的模块策略不一致
这些问题单独看都不大,但一旦混在一个仓库里,迁移节奏就会非常别扭。
我后来不再做“一次全改”
一开始我也想过一口气改完,后来发现更稳妥的方式是先把边界画出来:
- 哪些代码运行在浏览器
- 哪些运行在 Node
- 哪些只是构建期脚本
- 哪些模块会被多个环境同时消费
只有先把这些层次拆出来,才能知道哪里适合先迁、哪里应该暂时保持原样。
模块系统背后其实是在表达依赖关系
这也是我后来越来越认同的一点。
你选择 CommonJS 还是 ESM,不只是代码风格问题,它还会影响:
- 依赖如何被加载
- 工具链如何做静态分析
- 默认导入与具名导入怎么被理解
- 调试和构建错误会在哪里暴露
所以迁移时最值得先整理的,不是替换多少文件,而是仓库内部到底有没有清楚的模块边界。
小结
很多迁移项目卡住,不是因为大家不会写 import,而是因为过去的模块组织本来就有点乱,ES Module 只是把这份混乱照出来了。
如果边界清楚,迁移其实没那么可怕;如果边界不清楚,再优雅的语法也救不了工程上的糊涂账。
