最近组里要求我把几个老项目的包管理工具从 yarn
转为 pnpm
,因为新项目都使用 pnpm
,另外,还要求将前后端(NodeJS
)项目使用 monorepo
的方式组织在一个仓库里,并且保留历史 git信息
这里记录下替换和组织过程!
开始之前,需要了解 yarn
和 pnpm
的区别!
前端的包管理工具之所以层出不穷,从官方的 npm
到热门社区的 yarnpnpm
方案,再到一些新兴的 bunvolta
等, 其核心原因是由于依赖包版本更新快,管理越来越复杂,这是一个梗图!
负重前行
目前来说,社区没有完美的解决方案,都是侧重点不同,比如 yarn
可以做到锁文件版本,可以让不同环境的开发者,使用相同版本的依赖包!pnpm
通过硬链接节省磁盘空间,这种机制分别弥补了 npm
在这两种情况下的缺点!
另外,它们都有自己的特色功能,比如:pnpm
内置了 monorepo
管理能力,以及可插拔的 hook
生命周期和插件机制!
yarn
在 v2
中推出了 PNP
机制,抛弃 node_modules
目录,直接从 .pnp.js
加载依赖,加速启动速度,并减少磁盘文件数量,你可以将 .yarn/cache
和 .pnp.js
一起提交到 git
,这样 clone
项目后无需再执行 install
,即装即用!
说的有点多了,总结就是一句话:
pnpm
通过硬链接节省磁盘空间,并且内置了 monorepo
管理能力!
yarn
通过锁文件版本,有很强的一致性!
而我使用 pnpm
更多的原因是内置的 monorepo
能力!
说干就干,首先删除 node_modulesyarn.lock
文件,然后再在 package.json
文件中新增下面的配置,锁定包管理工具和版本:
"engines": {
"node": ">=18.0.0",
"pnpm": ">=8.0.0"
},
"packageManager": "pnpm@8.0.0",
然后执行 pnpm install
npm run dev
不出意外,肯定会报错,缺少某个包,这是正常的,因为 yarn
允许使用父级项目的依赖,而 pnpm
是不允许的!
这时候有两种方案,一种是将缺失的包,直接在 pnpm add xxx
添加进来!
另一种方案是允许使用父级依赖:pnpm install --node-linker=hoisted
具体使用哪种方案,你可以先运行下这个命令:
npx --yes depcheck
它可以列举项目中未使用、缺失的包,
Unused、Missing 情况
如果缺失的很多,推荐第二种,不多的话就一个一个下载吧!
新建文件夹,例如:demo,然后初始化
mkdir demo
cd demo
pnpm init
新建 pnpm-workspace.yaml
,新增如下配置
packages:
- 'packages/*'
新建 packages
文件夹,存放前后端子项目!
接下来是重头戏了,怎么保留原始 git
历史信息的情况下,将前后端项目保存在一个 git
仓库里?
首先你得下载一个工具库 git-filter-repo
:
brew install git-filter-repo
然后初始化git
,
git init
拉取一个裸仓库
git clone --bare https://xxxx/fe.git
然后进入这个临时项目
cd fe.git
使用 git-filter-repo
工具合并历史记录
git filter-repo --to-subdirectory-filter packages/fe
添加临时仓库
cd ..
git remote add fe ../demo/fe.git
拉去最新代码
git fetch fe
将 fe 的代码 合入过来
git merge fe/master --allow-unrelated-histories -m "feat: 合并代码"
清理临时临时仓即可
git remote remove fe
验证下是否有历史记录
git log -- packages/fe
并且可以看到在 packages
已经有了我们前端的代码了
接着重复上面的操作完成后端代码的迁移即可!
操作之后,你就可以看到完整的带有 git
历史记录的 monorepo
项目了!
我的历史记录
今天的分享就这些了,希望可以帮助到你!如果文章中有任何问题,欢迎指正!、