模块化和包管理
pnpm workspace 是个很有意思的用法,可以把各个子目录正式化为统一管理的程序模块,让各个模块存在转为可以通过 @xxx/xxx 形式引入的包。这种把多个模块聚合在一个仓库的架构,就叫做monorepo,他的好处就是all in one,全放在一起管理,而不需要在多个仓库(或者分散的文件夹,逻辑上和仓库类似)中跳来跳去,在维护和版控管理上要方便的多。
比如原先是
backend/ ← 后端,有自己的 package.json
frontend/ ← 前端,有自己的 package.json
shared/ ← 共享类型(靠手抄同步到 frontend)
而利用 pnpm workspace 就可以将整个项目转为
project/
├── pnpm-workspace.yaml ← 新增:声明 packages/* 是工作区成员
└── packages/
├── backend/ ← 原 backend
├── frontend/
└── shared/ ← 变成一个真正的包:@editorial/shared
这对于跨模块要共享同样类型或者契约来说是非常方便的。原先的分离文件夹形式还需要手动去核对,时间长非常容易飘,尤其是相对目录这种东西,一旦未来需要调整结构,基本上整个代码就得全改。因此,最简便且规整的方式就是将其抽象为包,交给包管理器统一调配。如果未来需要调整、扩展,都只需要在这个基础上顺延即可,非常方便。
同时还有依赖管理方面,也可以让所有模块的依赖进行统一管理,而不是各写各的。从供应链安全和可能的稳健性上来说,都比分散在各自的内部要好的多。对于ai时代的编程来说,相较于 基于过程的质量控制 里面提过的利用「微服务」来隔离各个仓库,monorepo 的代价会更低一点。尤其是运维上,搞个k8s多少还是负担太大了。整体上来说,微前端或者monorepo这种轻量级的模块化管理手段还是我更青睐的形式。
不过ai时代最大的优势就是「代码富裕」,架构开始逐渐胜于纯粹的「代码增量」。过去工程师可能会因为编码成本过高而放弃清晰且隔离的架构,因为整体上的维护和开发成本会增加。但今天,ai时代的开发成本被压缩到极致,反而是维护成本开始成为短板。此时,架构清晰的优势就会胜出——好测试、稳健性且低耦合的代码,在可维护性上远比庞杂的代码要更容易。尤其是对于ai开发来说,比起让它在依托难以名状的面条里面遨游,一改改成全局崩塌,还不如让它在清晰且界限明确的岛屿之间秩序通行。至少对于后者来说,即便出现问题,其边界也能严格控制在岛屿内部,但若是前者,连锁反应就可能导致塌陷式的全面崩塌。从稳健性上来说,显然是岛屿胜出。