从0开始使用pnpm构建一个Monorepo方式管理的demo

Monorepo这个词你应该不止一次听说了,像Vue3、Vite、ElementPlus等优秀开源项目都是使用Monorepo的方式管理项目,且这里说到的这几个项目都是采用pnpm作为包管理工具。
这篇文章就使用pnpm构建一个简单的Monorepo方式管理的项目。
🍊 什么是Monorepo?什么是pnpm?
Q:什么是Monorepo?
A:Monorepo是一种项目管理方式,就是把多个项目放在一个仓库里面,可以参考神三元大佬的一篇文章:现代前端工程为什么越来越离不开 Monorepo?,这篇文章中介绍了Monorepo的概念、收益以及MulitRepo的弊端。
Q:什么是pnpm?
A:pnpm就是一个包管理工具,原生支持Monorepo,比npm和yarn更快一些,其他的可以参考官网和神三元大佬的另一篇文章:为什么现在我更推荐 pnpm 而不是 npm/yarn?
🍌 搞一个Monorepo的demo玩玩
现在我们就开始使用pnpm来构建一个Monorepo,在正事开始之前,你先需要保证你的电脑中具有Node.js,我的版本的是16.9.0。
首先你需要有pnpm这个工具,安装的话可以从官网找方法,或者直接使用npm安装,命令如下:
npm i pnpm -g

现在我们开始搞事情。
第一步,创建一个项目的根目录,这里就叫monorepo-demo,咋创建都可,这里使用的是命令:
mkdir monorepo-demo

第二步,初始化package.json,这个没啥说的,命令如下:
pnpm init

这里我对内容做了一点修改,package.json的内容如下:
{
"name": "monorepo-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {

"test": "echo \"Error: no test specified\" && exit 1"

},
"type": "module",
"keywords": [],
"author": "ywanzhou",
"license": "MIT"
}

这里我主要添加了一个type字段,这里我使用ESModule模块化规范。
第三步,创建pnpm-workspace.yaml文件,这个文件定义了工作空间的根目录,内容如下:
packages:

  • 'packages/ **'

现在我们就可以在packages中创建多个项目了,目录结构如下:
monorepo-demo
├── package.json
├── packages
│ ├── components
│ │ ├── index.js
│ │ └── package.json
│ ├── core
│ │ ├── index.js
│ │ └── package.json
│ ├── utils
│ │ ├── index.js
│ │ └── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

第四步,编写每个项目的package.json,其实主要是编写一下名称,方便以后使用,这里我的如下:
{
"name": "@packages/components",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {

"test": "echo \"Error: no test specified\" && exit 1"

},
"keywords": [],
"author": "",
"type": "module",
"license": "ISC",
"dependencies": {

"lodash": "^4.17.21",
"@packages/utils": "workspace:^1.0.0"

}
}

剩余的两个名称分别为@packages/core和@packages/utils。
其实到这基本工作就准备好了,现在介绍一下如何安装依赖,如何在packageA中引用packageB。
🍋 安装依赖
就这个demo来说,我们如果在根目录下安装依赖的话,这个依赖可以在所有的packages中使用,如果我们需要为具体的一个package安装依赖怎么办?
cd到package的所在目录嘛?漏,大漏特漏,我们可以通过下面这个命令:
pnpm --filter <package_selector>

例如我们需要在@packages/components安装lodash,命令如下:
pnpm -F @packages/components add lodash

-F等价于--filter

现在我们在往@packages/utils中安装一个dayjs,命令如下:
pnpm --filter @packages/utils add dayjs

🍌 packageA中引用packageB
现在我们就来实现package间的相互引用,首先我们在@packages/utils/index.js中写入如下内容:
import dayjs from 'dayjs'
export function format(time, f = 'YYYY-MM-DD') {
return dayjs(time).format(f)
}

然后我们执行如下命令:
pnpm -F @packages/components add @packages/utils@*

这个命令表示在@packages/components安装@packages/utils,其中的@*表示默认同步最新版本,省去每次都要同步最新版本的问题。
安装完成后@packages/components/package.json内容如下:
{
"name": "@packages/components",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {

"test": "echo \"Error: no test specified\" && exit 1"

},
"keywords": [],
"author": "",
"type": "module",
"license": "ISC",
"dependencies": {

"@packages/utils": "workspace: *",
"lodash": "^4.17.21"

}
}

然后我们在@packages/components/index.js写入如下内容:
import { format } from '@packages/utils'
console.log(format(new Date()))

然后我们在项目根目录运行如下命令
node packages/components

即可打印出当前的日期。

<think>好的,我现在需要帮用户找到关于monorepo的详细教程或使用指南。首先,我得回顾用户提供的引用内容,看看里面有没有相关的信息。引用[2]提到了使用pnpm管理monorepo,推荐它作为2022年后的工具,因为它在处理依赖和提升体验方面表现很好。这里可能是一个重要的点,用户可能需要了解如何用pnpm搭建monorepo环境。 然后引用[3]比较了不同的工具,比如lerna和rush,指出lerna的上手成本高,需要yarn,而rush可能也有其复杂性。用户可能对选择哪个工具比较感兴趣,所以应该提到这些工具的优缺点,以及为什么推荐pnpm。 引用[1]提到package.json中的private设置为true,因为monorepo本身不发布,而是发布子项目。这可能涉及到配置方面的细节,用户需要知道如何正确设置他们的项目结构。 接下来,我需要整理一个结构清晰的教程步骤。首先介绍monorepo的概念,然后选择合适的工具,比如pnpm。接着是初始化项目,配置workspace,处理依赖管理,最后是构建和发布。每个步骤都需要结合引用中的信息,比如使用pnpm的workspace功能,设置package.json的private字段等。 可能用户还会关心如何管理内部依赖,比如子包之间的引用。这时候需要提到在子项目的package.json中使用workspace协议,如"dependencies": { "shared": "workspace:*" },这样pnpm会自动处理内部依赖。 另外,用户可能需要知道如何添加、构建和发布子项目。这里要分步骤说明,比如使用pnpm add安装依赖,通过pnpm -F指定子项目,以及使用变更集工具来管理版本和发布流程。 最后,应该包含常见问题,比如如何处理幽灵依赖,以及为什么选择pnpm而不是其他工具。这些问题可能在用户实际使用中会遇到,提前解答能帮助他们避免踩坑。 总结一下,回答需要涵盖工具选择、项目初始化、依赖管理构建发布流程,以及常见问题解答,结合用户提供的引用内容,确保信息准确且有参考依据。</think>### Monorepo 教程与使用指南详解 #### 1. **Monorepo 核心概念** Monorepo(单仓库)是一种将多个项目或模块存放在同一个代码仓库中的管理方式。其核心优势包括: - **代码共享便捷**:内部模块可直接引用,避免重复开发。 - **统一版本管理**:依赖和版本变更更易协调。 - **协作效率提升**:跨团队协作时,代码变更可见性高[^2]。 #### 2. **工具选择与配置** 当前主流的 Monorepo 管理工具推荐 **pnpm**,原因如下: - **高效依赖管理**:通过硬链接节省磁盘空间,加速安装速度。 - **原生 Workspace 支持**:无需复杂配置即可定义子模块关系[^2]。 - **避免幽灵依赖**:显式声明依赖,减少隐式依赖问题[^3]。 **初始化步骤**: ```bash # 全局安装 pnpm npm install -g pnpm # 创建项目目录并初始化 mkdir monorepo-demo && cd monorepo-demo pnpm init ``` #### 3. **Workspace 配置** 在根目录创建 `pnpm-workspace.yaml` 文件,定义子模块: ```yaml packages: - "packages/**" # 所有子项目存放在 packages 目录下 - "docs" # 可添加其他目录 ``` **子项目结构示例**: ``` monorepo-demo/ ├── package.json ├── pnpm-workspace.yaml └── packages/ ├── shared/ # 公共工具库 │ └── package.json └── app/ # 主应用 └── package.json ``` #### 4. **依赖管理实践** - **公共依赖**(如 React、TypeScript)安装到根目录: ```bash pnpm add react typescript -w ``` - **子项目专属依赖**(如 app 私有包): ```bash pnpm add lodash -F app ``` - **内部依赖引用**(app 依赖 shared): 在 `app/package.json` 中添加: ```json { "dependencies": { "shared": "workspace:*" } } ``` #### 5. **构建与发布流程** - **构建所有子项目**: ```bash pnpm -r run build ``` - **版本管理与发布**: 使用 `changesets` 工具管理版本变更: ```bash pnpm add @changesets/cli -w pnpm changeset # 生成变更记录 pnpm changeset publish # 发布版本 ``` 该工具支持自动生成 CHANGELOG 和协调子包版本号[^3]。 #### 6. **常见问题与优化** - **幽灵依赖问题**:通过 pnpm 的严格模式(`shamefully-hoist=false`)强制所有依赖显式声明[^3]。 - **跨平台协作**:建议搭配 Git 子模块或 Plastic SCM 实现高效代码同步[^4]。 - **性能优化**:利用 pnpm 的过滤命令仅构建受影响模块: ```bash pnpm --filter=app... run build ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值