下班之后没人亲亲,敲段代码哄自己开心。写个demo修完bug,誓让女神喊你哥哥。
背景
我们有两个产品项目,最初用 pnpm workspace 管理公共代码,后来把公共部分抽离成独立仓库,改用 Git Submodule 引用。直到最近修改公共逻辑,才发现这个决策有多坑,分享下缺点,帮你避开这些坑。
痛点1 克隆和初始化极其麻烦
新同事拉代码后,经常遇到这种情况:
# 克隆主项目
git clone https://github.com/xxx/main-project.git
cd main-project
# 发现 shared 目录是空的!
ls packages/shared/ # 空目录
# 需要手动初始化 submodule
git submodule init
git submodule update
# 或者克隆时加上 --recurse-submodules
git clone --recurse-submodules https://github.com/xxx/main-project.git
问题:
- 忘了初始化 submodule,代码跑不起来
- CI/CD 管道经常漏配置 —recurse-submodules
- 新同事上手成本高
痛点 2:版本锁定导致更新困难
Submodule 本质上是一个 固定的 commit 引用,不是分支,当你修改了 shared 仓库,主项目 不会自动更新,要更新主项目对 submodule 的引用,需要手动操作:
# 克隆主项目
cd packages/shared
git pull origin main # 更新 submodule
cd ../..
git add packages/shared
git commit -m "chore: update shared submodule"
git push
问题:
- 修改公共代码需要 两次提交、两次推送
- 容易忘记提交主项目的引用更新
- 团队协作时,其他人可能用到旧版本
痛点 3:分支切换时的噩梦
切换主项目分支时,submodule 的状态不会自动切换,如果你在 submodule 里做了修改但没推送,切换主项目分支会导致 代码丢失 或 冲突
# 克隆主项目
# 在主项目的 feature 分支
git checkout feature-branch
# submodule 可能还指向旧分支的 commit!
# 需要手动同步
git submodule update --init --recursive
真实案例:一次公共逻辑的修改
上周,我需要修改公共代码中的一个工具函数。整个流程是这样的: 步骤 1:修改公共代码
# 进入 submodule 目录
cd packages/shared
# 创建新分支
git checkout -b fix/timeout-handling
# 修改代码
vim src/utils/request.ts
# 提交到 submodule 仓库
git add .
git commit -m "fix: 改进超时处理逻辑"
git push origin fix/timeout-handling
# 合并到 main(假设走 PR 流程)
# ... 等待 code review ...
步骤 2:更新主项目引用
# 回到主项目
cd ../..
# 更新 submodule 引用
git add packages/shared
git commit -m "chore: update shared to latest version"
git push
步骤 3:通知团队成员
在团队群里发消息
“大家好,我更新了 shared 库,请大家 pull 代码后执行: git submodule update —init —recursive”
步骤 4:处理问题
结果还是出问题了:
有同事忘了执行 submodule update,用了旧代码 CI 构建失败,因为没配置 submodule token 另一个同事在 feature 分支,submodule 引用冲突 整个流程非常耗时及其不稳定,而如果用在 pnpm workspace 里,可能 10 分钟 就搞定了。
总结
没事不要瞎捣鼓submodule,pnpm workspace 能解决的问题,不要用更复杂的方案,事实证明pnpm workspace能解决80%以上的问题。