在过去的 1 年多时间里,我们一直在使用 pnpm
单一仓库来管理项目。随着项目数量的不断增加,深刻体会到了单一仓库的强大优势。通过 pnpm
,不仅实现了公共物料的复用,还显著节省了开发时间,提升了开发效率。当然,在开发过程中也遇到了不少挑战,但这些经历都促使自己不断优化和改进。
通过记录这些实践和经验,希望能够更好地发现问题、解决问题,并在此过程中不断成长。
直接进入主题------从 0 搭建一个 pnpm 单仓:
1. 创建项目目录
首先创建一个根目录 mocha-monorepo
,用于存放整个单一仓库的代码
bash
mkdir mocha-monorepo && cd mocha-monorepo
2. 初始化项目
在根目录下初始化项目,创建 package.json
文件,运行命令:
csharp
pnpm init
生成的package.json文件,手动添加 "private": true
bash
{
"name": "mocha-monorepo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"private": true
}
3. 配置 pnpm-workspace.yaml
单一仓库(Monorepo)的目录结构并没有固定的模式,完全可以根据项目的实际需求和团队的习惯进行设计。在此我采用 packages
和 apps
这样的目录结构,这是比较常见且推荐的方式,它能够很好地平衡模块化和集中管理的需求,当然,随着开发的深入,你可以随时优化目录结构以适应自己的开发习惯。
bash
mocha-monorepo/
├── packages/
│ ├── components/ # 公共组件库
│ ├── directives/ # 公共指令
│ ├── composables/ # 公共composables
│ ├── utils/ # 公用工具函数
│ └── apis/ # API 客户端库
│ └── assets/ # 公共静态资源
├── apps/
│ ├── web-app/ # Web 应用
│ ├── mobile-app/ # 移动应用
│ └── admin-dashboard/ # 管理后台
├── scripts/ # 构建、部署等脚本
├── docs/ # 文档
├── package.json # 根级依赖管理
├── pnpm-workspace.yaml # pnpm 工作空间配置(如果使用 pnpm)
└── README.md # 项目说明
└── ...
根据以上目录机构,在根目录下创建 pnpm-workspace.yaml
文件,定义工作区中的包路径。这表示所有位于 packages/
、app/
、docs/
下的目录都被视为独立的包
vbnet
packages:
- 'packages/*'
- 'apps/*'
- 'docs/**'
4. 创建子项目
在 apps/
目录下创建子项目。例如
java
cd apps
pnpm create vite@latest
// 按照提示选择,并创建项目
pnpm i
pnpm dev
和我们创建一个普通 Vite 应用是一样的,创建完成后,安装依赖并运行,可以看到熟悉的 Vite+Vue 页面。
到此为止,这个 pnpm 的单一仓库(mono-repo)和普通多仓库(muti-repo) 差不多。接下来,我们会逐步配置和优化这个单仓,发挥单仓的优势。
5. 实现一个简单的公共方法
照例从最简单的入手,我们在packages/utils/文件下创建一个index.ts文件
bash
cd packages/utils
touch index.ts
创建一个简单的方法并导出
javascript
export const hello = () => {
return 'hello world'
};
接下来,就是在 apps/app1 中使用这个 hello
方法,显然直接引用是做不到的,我们需要建立各个包/项目的相互联系。
6. 初始化 packages/utils
为一个 npm 包
为了让 packages/utils
能够作为一个可复用的包被其他项目引用,我们需要为其创建一个 package.json
文件。在packages/utils 下运行
csharp
pnmp init
编辑生成的 package.json
文件,修改 "name" 为 "@mocha-monorepo/utils"
perl
{
"name": "@mocha-monorepo/utils",
"version": "1.0.0",
"description": "",
"main": "index.js",
"keywords": [],
"author": "",
"license": "ISC"
}
7. 安装utils 到 app1中
这里有一个小小的坑,如果直接使用下面的命令安装,很可能会失败
sql
pnpm add @mocha-monorepo/utils

这里需要修改一下命令,增加@workspace:^
,明确告诉终端我们是从workspace中安装。
ruby
pnpm add @mocha-monorepo/utils@workspace:^
查看app1/package.json
,dependencies
已经有了utils
包

8. 在 app1 中使用utils的方法
修改 app1/App.vue 的代码
xml
<script setup lang="ts">
import {hello} from '@mocha-monorepo/utils'
const str = hello()
</script>
<template>
<div> 这是来自utils的: {{ str }}</div>
</template>
运行到浏览器,查看效果:

OK,成功的第一步已经迈出了~
在后续的文章中,将继续深入探讨单一仓库的配置和优化,分享更多实践经验,帮助大家更好地利用 pnpm
单一仓库提升开发效率。
有任何问题或者兴趣也可以在公众号:自由前端之路 找到我。