一、为什么要用Yarn workspace管理多包项目
想象一下你正在开发一个电商平台,需要同时维护前端React组件库、后端Node.js微服务和共享的工具函数库。如果每个项目单独放在不同仓库,会出现这样的烦恼:
- 改个工具函数要同时在三个仓库提交代码
- 本地调试时需要反复
npm link - 团队新人要clone十几个仓库才能开始开发
Yarn workspace就像个智能文件夹管理器,它可以把多个相关项目放在同一个大仓库(monorepo)里,还能自动处理它们之间的依赖关系。我们来看个实际例子:
// 技术栈:Node.js + Yarn
// 项目结构示例:
my-monorepo/
├── package.json
├── packages/
│ ├── frontend/ # 前端项目
│ │ └── package.json
│ ├── backend/ # 后端API
│ │ └── package.json
│ └── utils/ # 共享工具库
│ └── package.json
二、快速搭建你的第一个workspace
让我们从零开始搭建。首先确保安装了Yarn 1.x以上版本,然后执行:
mkdir my-monorepo && cd my-monorepo
yarn init -y
接着修改根目录的package.json:
{
"name": "my-monorepo",
"private": true,
"workspaces": ["packages/*"], // 关键配置:声明workspace目录
"scripts": {
"start": "yarn workspace frontend start"
}
}
现在创建三个子包:
mkdir -p packages/{frontend,backend,utils}
# 初始化前端项目
cd packages/frontend && yarn init -y
echo "console.log('前端启动');" > index.js
# 初始化后端项目
cd ../backend && yarn init -y
echo "console.log('API服务启动');" > index.js
# 初始化工具库
cd ../utils && yarn init -y
echo "exports.add = (a,b) => a + b;" > math.js
三、让包之间产生化学反应
假设前端需要用到工具库的add方法,传统方式要发布npm包或者用npm link。在workspace里只需:
// 在packages/frontend/package.json中添加
{
"dependencies": {
"utils": "1.0.0" // 版本号要与utils包的package.json一致
}
}
然后运行yarn install,神奇的事情发生了:
- Yarn会自动创建软链接,把utils映射到node_modules
- 修改utils代码会实时生效,不需要重新安装
- 所有依赖会被提升到根node_modules,避免重复安装
我们可以在前端代码中直接使用:
// packages/frontend/index.js
const { add } = require('utils/math');
console.log(`1 + 2 = ${add(1, 2)}`);
四、进阶技巧:跨包脚本与依赖管理
- 统一运行命令:在根package.json中添加:
{
"scripts": {
"build:all": "yarn workspaces run build",
"test:all": "yarn workspaces run test"
}
}
- 处理peerDependencies:当多个包依赖不同版本的React时,可以这样解决:
// 在根package.json中添加
{
"resolutions": {
"react": "17.0.2",
"react-dom": "17.0.2"
}
}
- 选择性安装:只想给某个包装依赖?
yarn workspace frontend add lodash
五、实际开发中的场景与技巧
场景1:调试本地依赖 当utils包修改后,不需要发布或重新链接,前端项目能立即使用最新代码。
场景2:统一代码风格 在根目录添加.eslintrc和.prettierrc,所有子包继承配置。
场景3:CI/CD优化 只构建改动的包,比如通过git diff检测变更:
# 只构建发生变更的包
changed_packages=$(git diff --name-only HEAD~1 | grep 'packages/' | cut -d/ -f2 | uniq)
for pkg in $changed_packages; do
yarn workspace $pkg build
done
六、优缺点与注意事项
优点:
- 依赖管理更智能,减少磁盘空间占用
- 跨项目修改更安全,所有代码在一起
- 统一工具链配置更方便
- 适合组件库+演示项目协同开发
缺点:
- 仓库体积会随时间增长
- 需要规范提交信息(建议用commitizen)
- IDE可能需要额外配置(VSCode需要打开根目录)
注意事项:
- 不要直接修改node_modules中的workspace包代码
- 慎用
yarn add不加-W参数,可能会装错地方 - 子包之间避免循环依赖
- 建议用changesets管理版本发布
七、版本发布的艺术
发布workspace项目需要特殊处理,推荐流程:
- 安装changesets工具:
yarn add -W @changesets/cli
yarn changeset init
- 生成变更记录:
yarn changeset # 交互式选择要发布的包
- 版本提升与发布:
yarn changeset version
git push --follow-tags
yarn workspaces foreach run publish
八、总结与最佳实践
经过实际项目验证,我们总结出这些经验:
- 按功能而非技术划分子包(如
payment-service而非node-server) - 共享配置放在根目录(eslint、jest、typescript配置)
- 使用TurboRepo或Nx加速构建
- 重要项目独立CI流水线
- 文档统一放在根目录docs文件夹
记住:monorepo不是银弹,适合跨团队协作的中大型项目。如果是小型独立项目,传统多仓库可能更简单。
评论