pnpm + monorepo:高效的项目管理方式

pnpm + monorepo: 高效的项目管理方式

前言

在进行多项目管理时,一般有两种方式,multirepomonorepo

multirepo

multirepo 是将每个项目或者模块分别放在各自的 git 仓库里,需要对每个仓库单独维护。

项目架构如下:

zsh 复制代码
app/    # 项目A (git@github.com/app.git)
app2/   # 项目B (git@github.com/app2.git)
share/  # 公共模块 (git@github.com/share.git)

monorepo

monorepo 是将多个项目或者模块放在同一个仓库里,除了有公共的 packages.json 之外,每个项目都有自己的 packages.json

对应公共的依赖可以安装到公共的 node_modules 里,而每个项目的依赖则安装到各自的 node_modules 里,实现依赖共享

同时,每个子模块之间可以实现互相引用,而不需要发布成 npm 包,管理更加高效。

项目架构如下:

zsh 复制代码
- monorepo/
 - packages/
   - app/   # 项目A
   - app2/  # 项目B
   - share/ # 公共模块
- package.json

pnpm + monorepo

接下来讲一下如何使用 pnpm + monorepo 来进行多项目管理。

安装 pnpm

首先,全局安装 pnpm

zsh 复制代码
npm install -g pnpm

初始化 monorepo

创建一个 pnpm-monorepo 文件夹,然后通过 pnpm init 创建 package.json

zsh 复制代码
mkdir pnpm-monorepo
cd pnpm-monorepo
pnpm init
json 复制代码
// package.json
{
  "name": "pnpm-monorepo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

然后,创建一个 packages 文件夹,用来存放子模块。

我们在 packages 文件夹下创建两个子模块:appshare

对于app 模块,我们用 pnpm create vite app 创建一个 vue 项目。

zsh 复制代码
cd packages
pnpm create vite app
json 复制代码
// packages/app/package.json
{
  "name": "app",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.5.13"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.2.2",
    "vite": "^6.3.1"
  }
}

而对于share 模块,我们用 pnpm init 初始化一个项目,然后新建一个 index.js 文件。作为入口文件,在里面暴露一个公共方法:

javascript 复制代码
// packages/share/index.js
function add(a, b) {
  return a + b;
}
export default { add };
json 复制代码
// packages/share/package.json
{
  "name": "share",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

配置 workspace

pnpm-monorepo 文件夹下,创建 pnpm-workspace.yaml 文件,配置子模块。

yaml 复制代码
# pnpm-workspace.yaml
packages:
  - 'packages/*' # 指定 packages 目录下所有模块都为 monorepo 的子模块

这个时候一个基本的 monorepo 项目架构就创建好了:

zsh 复制代码
- pnpm-monorepo/
 - packages/
   - app/   # vue 项目
   - share/ # 公共模块
 - pnpm-workspace.yaml
 - package.json

依赖管理

如果在根目录下 执行 pnpm install,会自动安装根目录和所有子包的依赖项。

如果我们想分别安装依赖,可以通过指定参数来控制。

安装公共依赖

公共依赖是每个子模块都会用到的依赖,我们可以安装到公共的 node_modules 里。

比如,我们的 vue 项目和 share 模块都依赖了 lodash-es 模块,那么就可以作为公共依赖安装。

通过添加 -w 参数,可以安装到根目录的node_modules 里。

-w--workspace-root 的简写。

zsh 复制代码
pnpm i lodash-es -w
安装子模块依赖

子模块自己用到的依赖可以安装到各自的 node_modules 里。

比如,只有 vue 项目里用到了 axios 模块,那么就可以安装到 app 项目的 node_modules 里。

通过 --filter <package-name> 参数,可以指定安装到哪个子模块的 node_modules 里。

--filter 可以简写为 -F

注意,这里的 package-namepackage.json文件中的 name 字段。

zsh 复制代码
pnpm i axios --filter app

模块共享

如果我想在 vue 项目里引用 share 模块的 add 方法,需要将 share 模块安装到 app 项目的 node_modules 里。

可以通过 --workspace 参数,告诉 pnpm 去当前 workspace 查找相关模块。

zsh 复制代码
pnpm i share --filter app --workspace

这时 app 项目的 packages.json 文件就会多一个 share 模块的依赖。

json 复制代码
...
"dependencies": {
  "share": "workspace:^",
  "vue": "^3.5.13"
}
...

其中,workspace 表示当前工作空间,^ 表示安装最新版本。

也可以通过在 package.json 的依赖里声明 "share": "workspace:^",也可以指定具体的版本号。这样在安装时就不需要添加 --workspace 参数了。

如果想把 share 模块作为公共依赖安装的话,在后面再加一个 -w 参数就可以了。

zsh 复制代码
pnpm i share --workspace -w

总结

  • pnpm i :安装所有的依赖,包括公共依赖和子模块依赖。
  • pnpm i -w :安装公共依赖到根目录的 node_modules 里。
  • pnpm i --filter <package-name> :安装指定子模块的依赖到 node_modules 里。
  • pnpm i <package-name1> --filter <package-name2> --workspace :安装当前 workspace中的模块到指定项目的 node_modules 里。
  • pnpm i --workspace -w :安装当前 workspace中的模块到根目录的 node_modules 里。
相关推荐
paopaokaka_luck32 分钟前
基于SpringBoot+Uniapp的健身饮食小程序(协同过滤算法、地图组件)
前端·javascript·vue.js·spring boot·后端·小程序·uni-app
患得患失9491 小时前
【前端】【vscode】【.vscode/settings.json】为单个项目配置自动格式化和开发环境
前端·vscode·json
飛_1 小时前
解决VSCode无法加载Json架构问题
java·服务器·前端
YGY Webgis糕手之路4 小时前
OpenLayers 综合案例-轨迹回放
前端·经验分享·笔记·vue·web
90后的晨仔4 小时前
🚨XSS 攻击全解:什么是跨站脚本攻击?前端如何防御?
前端·vue.js
Ares-Wang4 小时前
JavaScript》》JS》 Var、Let、Const 大总结
开发语言·前端·javascript
90后的晨仔4 小时前
Vue 模板语法完全指南:从插值表达式到动态指令,彻底搞懂 Vue 模板语言
前端·vue.js
德育处主任4 小时前
p5.js 正方形square的基础用法
前端·数据可视化·canvas
烛阴4 小时前
Mix - Bilinear Interpolation
前端·webgl
90后的晨仔5 小时前
Vue 3 应用实例详解:从 createApp 到 mount,你真正掌握了吗?
前端·vue.js