前端时间自己在新项目中使用了monorepo工程化的思路,做了一个《低代码开发平台》的项目,但是一直没有好好的写一写案例,今天就好好写一个入门级的案例操作步骤:
Monorepo(单一代码仓库) 是一种项目管理模式:
将多个相关项目(或子包)存储在同一个代码仓库中,而非分散到多个独立仓库。
这篇文章就不过多的描述了。
Monorepo 的实现可以通过多种工具和技术栈完成,主要分为以下三类:
(1)pnpm :
(2) Yarn:
(3)npm V7+
我是有npm的,所以我采用npm 指令安装,也可以从官网找方法。
npm i pnpm -g
第一步
:创建了一个文件夹叫做“ monorepo-demo ”,也可以指令创建
mkdir monorepo-demo
第二步
:初始化:
在monorepo-demo文件夹的根目录下进行初始化:
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",//这是添加的一个属性,通过 "type": "module" 启用现代 ES6 模块语法(需 Node.js ≥ 13.2.0)
"keywords": [],
"author": "tty",
"license": "ISC"
}
第三步
:创建pnpm-workspace.yaml文件,这个文件定义了工作空间的根目录,内容如下:
此配置是 pnpm monorepo 的基石,确保正确识别所有本地包并启用工作区依赖链接机制。
packages:
- 'packages/**'
核心含义:
(1)packages:
• 声明工作区(workspace)的根路径规则,
用于告诉 pnpm 哪些目录属于 monorepo 的子包。
(2) - 'packages/**'
• packages/:项目根目录下的 packages 文件夹
• **:递归匹配符(Glob 语法),表示 packages 目录下任意层级的子目录
• 组合含义:将 packages 目录及其所有子目录识别为 monorepo 的子包
✅ 匹配范围:
所有位于 packages/ 下的目录(无论嵌套多深),只要包含 package.json 文件就会被 pnpm 视为工作区子包。
monorepo/
├── packages/
│ ├── web/ # 会被识别
│ │ └── package.json
│ ├── utils/
│ │ ├── core/ # 会被识别(嵌套子目录)
│ │ │ └── package.json
│ │ └── helpers/ # 会被识别
│ │ └── package.json
│ └── mobile/ # 会被识别
│ └── package.json
├── docs/ # 不会被识别(不在 packages/ 下)
│ └── package.json
└── pnpm-workspace.yaml # 配置文件
对比其他写法
如需排除测试目录,可添加排除规则,也可同时监控多个目录:
packages:
- 'packages/**'
- '!**/__tests__/**' # 忽略所有 __tests__ 目录
- 'apps/**' # 增加 apps 目录作为工作区
- 'libs/**' # 增加 libs 目录
第四步
:在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
在 Monorepo 架构中,packages 文件夹是一个核心设计,主要用于实现 模块化组织、代码复用 和 工程规范统一。
模块化组织与代码隔离
第五步
:编写每个项目的package.json,其实主要是编写一下名称,方便以后使用。
{
"name": "@packages/components",//主要是改这里
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "tty",
"type": "module",
"license": "ISC",
}
packages 下面的一级子目录也同理操作:
剩余的名称分别为@packages/core和@packages/utils。
·第六步
:安装依赖
如果在根目录下安装依赖的话,这个依赖可以在所有的packages中使用,如果我们需要为具体的一个package安装依赖怎么办?不要在某一package中安装,依然在根目录下安装
pnpm -F @packages/components add lodash
pnpm --filter @packages/utils add dayjs
其中 -F等价于--filter
这是安装以后得样子:
第8步:在packageA中引入packageB
pnpm -F @packages/components add @packages/utils@workspace:*