pnpm+monorepo架构开发前端项目(转载)
一、前期准备:
1. 准备node环境(推荐nvm方式管理node版本);
2.安装pnpm(pnpm 通过创新存储模型解决了 npm/yarn 的磁盘冗余、依赖污染等核心痛点,尤其适合 Monorepo 项目、低存储环境及高稳定性要求的场景。若项目无特殊兼容需求,pnpm 是当前最优解。);
npm i pnpm -g
二、创建项目:
1.使用pnpm初始化项目:
pnpm init
2.创建pnpm-workspace.yaml文件
该文件用于在 Monorepo 项目中统一管理多个子包间的依赖关系和构建流程。是pnpm 工作区(Workspace)核心配置文件
-
- 创建方式:
1.手动创建
-
- 作用:
1.定义工作区范围
packages: - "packages/**" # 递归匹配所有嵌套子包 - "apps/*" # 匹配 apps 一级目录下的子包 - "demo" # 单独指定 demo 目录
子包需要满足:
-
-
- 包含独立的
package.json且声明name字段 - 目录路径匹配配置文件中的规则
- 包含独立的
-
2.实现跨包依赖共享
3.统一依赖管理:根目录运行 pnpm install 可一次性安装所有子包依赖,并自动处理内部链接
三、pnpm-workspace.yaml配置:
如何配置:
- 1.配置工作区内容**packages**:必要
pnpm-workspace.yaml文件配置 packages: # 可单独设置项目:表示一个具体包名 - main_project # 表示 web 目录下的所有子包 - web/*
- 2.配置全局依赖*catalog*:
作用:管理配置多项目依赖,实现跨包依赖共享、统一依赖管理;
配置方法:
catalog: "@vue/tsconfig": ^0.7.0 axios: ^1.10.0 mockjs: ^1.1.0 jsdom: ^26.1.0 prettier: ^3.5.3 vite: ^6.3.5
使用方法:在前端项目目录下的package.json中使用
"dependencies": {
"axios": "catalog:"
},
"devDependencies": {
"mockjs": "catalog:",
}
- 3.配置具名依赖*catalogs*:
作用:配置自定义依赖,可设置单项目支持依赖,自定义区分多框架项目依赖;
配置方法:
catalogs:
vue3:
vue: ^3.5.17
...
vue2:
vue: 2.7.16
...
react:
react: ^19.1.0
...
使用方法:在前端项目目录下的package.json中使用;*注意:.yaml文件中配置时需要加s,使用时不需要加s*
"dependencies": {
"vue": "catalog:vue3",
},
"devDependencies": {
"unplugin-vue-components": "catalog:vue3",
}
四、在 pnpm+Monorepo 架构中创建 Vue3 子项目:
进入monorepo架构目录创建web目录
|-- your-monorepo
|-- package.json
|-- pnpm-lock.yaml
|-- pnpm-workspace.yaml
|-- web
进入web目录,通过vite创建vue项目:

依次选择自己想要使用的开发框架和语言支持不再多赘述。
创建完成后,修改main_project项目的package.json文件:
- 修改name添加组织作用域
- 修改依赖项

cd回到根目录运行pnpm i 或 pnpm install安装依赖:

查看main_project项目node_modules文件夹下查看是否安装成功:

安装成功后,选择根目录package.json配置运行脚本
"main_project:dev": "pnpm -F main_project run dev"

test可以删除掉,
运行pnpm run main_project:dev

点击local后链接,或直接打开浏览器输入链接即可运行项目
五、给某个package单独安装指定依赖:
. ├── README.md ├── package.json ├── packages │ ├── pkg1 │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ └── pkg2 │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── pnpm-workspace.yaml └── tsconfig.root.json
上面是项目结构,先在工程根目录下新建 packages 目录,并且在 packages 目录下创建 pkg1 和 pkg2 两个工程,分别进到 pkg1 和 pkg2 两个目录下,执行 npm init 命令,初始化两个工程,package.json 中的 name 字段分别叫做 @qftjs/menorepo1 和 @qftjs/monorepo2
安装依赖包
使用 pnpm 安装依赖包一般分以下几种情况:
- 全局的公共依赖包,比如打包涉及到的
rollup、typescript等
pnpm 提供了 -w, --workspace-root 参数,可以将依赖包安装到工程的根目录下,作为所有 package 的公共依赖。
比如:
$ pnpm install react -w
如果是一个开发依赖的话,可以加上 -D 参数,表示这是一个开发依赖,会装到 pacakage.json 中的 devDependencies 中,比如:
$ pnpm install rollup -wD
- 给某个package单独安装指定依赖
pnpm 提供了 --filter 参数,可以用来对特定的package进行某些操作。
因此,如果想给 pkg1 安装一个依赖包,比如 axios,可以进行如下操作:
$ pnpm add axios --filter @qftjs/monorepo1
需要注意的是,--filter 参数跟着的是package下的 package.json 的 name 字段,并不是目录名。
关于 --filter 操作其实还是很丰富的,比如执行 pkg1 下的 scripts 脚本:
$ pnpm build --filter @qftjs/monorepo1
filter 后面除了可以指定具体的包名,还可以跟着匹配规则来指定对匹配上规则的包进行操作,比如:
$ pnpm build --filter "./packages/**"
此命令会执行所有 package 下的 build 命令。具体的用法可以参考filter文档。
- 模块之间的相互依赖
最后一种就是我们在开发时经常遇到的场景,比如 pkg1 中将 pkg2 作为依赖进行安装。
基于 pnpm 提供的 workspace:协议,可以方便在 packages 内部进行互相引用。比如在 pkg1 中引用 pkg2:
$ pnpm install @qftjs/monorepo2 -r --filter @qftjs/monorepo1
此时我们查看 pkg1 的 package.json,可以看到 dependencies 字段中多了对 @qftjs/monorepo2 的引用,以 workspace: 开头,后面跟着具体的版本号。
{ "name": "@qftjs/monorepo1", "version": "1.0.0", "dependencies": { "@qftjs/monorepo2": "workspace:^1.0.0", "axios": "^0.27.2" } }
在设置依赖版本的时候推荐用 workspace:*,这样就可以保持依赖的版本是工作空间里最新版本,不需要每次手动更新依赖版本。
当 pnpm publish 的时候,会自动将 package.json 中的 workspace 修正为对应的版本号。
{ "name": "@qftjs/monorepo1", "version": "1.0.0", "dependencies": { "@qftjs/monorepo2": "workspace:*", "axios": "^0.27.2" } }
项目地址:https://gitee.com/cheng_zhen_guo/blog_demo_monorepo/tree/master


浙公网安备 33010602011771号