使用pnpm + workspace搭建Monorepo项目架构🐱🐉
前言
为什么用Monorepo模式?
Monorepo是一种单一代码仓库的开发模式,在一个代码仓库里面开发多个项目,方便共享组件和依赖,降低维护多个仓库的成本。
为什么用pnpm包管理工具?
pnpm不仅可以提高构建速度,解决幽灵依赖问题,还提供了对工作区(workspace)的支持,允许在单个代码库中管理多个项目或包。
项目环境
项目环境:node v22.16.0 、npm v10.9.2
项目技术栈:Vite 、Vue3.5 、Pinia 、vue-router4.5 、Scss 、Tailwindcss 、vue-i18n
cursor编辑器
什么编辑器都可以,用自己最舒服的就好了。
拓展插件
Chinese (Simplified) (简体中文)
:中文语言支持Auto Close Tag
:自动闭合标签Auto Complete Tag
:自动补全标签Prettier
:代码风格检查ESLint
:代码格式化Vue(Oficial)
:Vue3语法支持
安装包管理工具
整个项目使用pnpm构建
js
npm install pnpm -g
初始化Monorepo项目结构
创建项目根目录yummy-monorepo
,在根目录运行pnpm init
初始化pacakge.json
文件
js
pnpm init
在根目录新建文件夹pakages
和libraries
,用于存储子包。
js
yummy-monorepo/
├──libraries/
├──packages/
└──package.json
新建yummy-utils
共享包,
js
yummy-monorepo/
├──libraries/
│ └──yummy-utils/
│ ├──src/
│ │ └──index.js
│ └──package.json
├──packages/
└──package.json
在yummy-utils
文件夹中运行pnpm int
初始化package.json
文件,修改package.json
里面的name 为@yummy/utils
;修改package.json
里面的main 入口为src/index.js
。
js
{
"name": "@yummy/utils",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.11.0"
}
配置workspace
根目录新建一个 pnpm-workspace.yaml
,将 packages 下所有的目录都作为包进行管理。
js
// pnpm-workspace.yaml
packages:
- 'packages/*'
- 'libraries/*'
Monorepo最终项目结构
js
yummy-monorepo/
├──libraries/
│ └──yummy-utils/
├──packages/
├──package.json
└──pnpm-workspace.yaml
共享子包@yummy-utils
用-w
把包安装在根目录
用--workspace
参数去安装共享子包,会去 workspace工作空间中找依赖项并安装,不去寻找npm的同名远程包
js
pnpm i @yummy/utils -w --workspace
package.json
会出现依赖项
js
"dependencies": {
"@yummy/utils": "workspace:*"
}
这时,其他子包项目就可以使用公共包@yummy/utils
里的方法,import引入即可
js
import { } from '@yummy/utils'
安装公共/局部依赖
公共依赖
js
pnpm install xxx -w
局部依赖 cd指定项目路径,正常安装即可
搭建vue项目
初始化
进入pacakges
路径,执行命令:pnpm create vite
,选择Vue
和TypeScript
js
> pnpm create vite
Project name:
│ yummy-main
│
◆ Select a framework:
│ ○ Vanilla
│ ● Vue
│ ○ React
◆ Select a variant:
│ ● TypeScript
│ ○ JavaScript
│ ○ Official Vue Starter ↗
│ ○ Nuxt ↗
└
创建子包项目后目录结构如下
js
yummy-monorepo/
├──libraries/
│ └──yummy-utils/
├──packages/
│ └──yummy-main/
├──package.json
└──pnpm-workspace.yaml
Vue项目目录结构
js
yummy-main/
├──public/ # 公共资源
├──src/
│ ├──api/ # 接口
│ ├──assets/ # 静态资源
│ │ ├──images/
│ │ └──svgs/
│ ├──config/ # 全局配置
│ ├──directive/ # 自定义插件
│ ├──hooks/ # 函数钩子
│ ├──locales/ # 国际化资源
│ ├──router/ # 路由配置
│ ├──stores/ # 全局状态管理
│ ├──styles/ # 全局样式
│ ├──types/ # 全局类型声明
│ ├──utils/ # 工具库
│ ├──views/ # 业务页面入口和常用模板
│ ├──App.vue # Vue 模板入口
│ ├──main.ts # Vue 入口 ts
│ └──permission.ts # 路由守卫(路由全局控制)
├──.env # 环境变量
├──.gitignore # git忽略配置文件
├──index.html
├──pacakge.json
├──tsconfig.app.json
├──tsconfig.json
├──tsconfig.node.json
└──vite.config.ts