文档作者: Jannik

什么是Monorepo
Monorepo 即单体版本库,是一种将多个项目的代码存储在一个版本控制系统(如 Git)仓库中的软件开发策略,以下是关于它的详细介绍:
基本概念
- 定义:Monorepo 把所有相关的项目代码都放在一个仓库中进行管理,这些项目可以是不同的应用程序、库、工具等,但它们在某种程度上相互关联或属于同一个产品体系。
- 与传统多仓库的对比:传统的软件开发通常采用多仓库模式,即每个项目都有自己独立的版本库。而 Monorepo 则将所有项目整合到一个仓库中,方便统一管理和代码共享。
优势
- 代码共享与复用:在 Monorepo 中,不同项目之间可以方便地共享代码。如果多个项目都需要使用某个公共的功能或库,只需要在 Monorepo 中维护一份代码,各个项目都可以直接引用,避免了代码的重复编写和维护。
- 统一的工作流程和规范:所有项目在一个仓库中,便于制定统一的代码规范、提交规范、构建流程等。开发人员可以遵循相同的标准进行开发,提高代码质量和可维护性。
- 原子提交:由于所有项目在一个仓库中,一次提交可以涵盖多个项目的相关更改,保证了提交的原子性。这使得版本历史更加清晰,便于追踪整个系统的变更过程。
- 依赖管理简化:Monorepo 中各个项目之间的依赖关系更加明确和易于管理。可以通过统一的依赖管理工具,方便地管理项目之间的依赖版本,避免了多仓库模式下可能出现的依赖冲突问题。
适用场景
- 大型项目或项目群:适用于大型的企业级项目或由多个相关子项目组成的项目群,如大型电商平台、综合性金融系统等,这些项目通常需要多个团队协同开发,代码共享和复用的需求较高。
- 开源项目集合:一些开源组织会将多个相关的开源项目放在一个 Monorepo 中进行管理,方便开发者对整个项目生态系统进行贡献和维护。
Monorepo(单体仓库)与 MultiRepo(多仓库)
Monorepo 和 MultiRepo 简介
在软件开发中,代码仓库的管理方式对项目的效率和协作有着重要影响。常见的代码仓库管理方式主要有两种:Monorepo(单体仓库)和 MultiRepo(多仓库)。

- Monorepo(单体仓库) :是指将多个项目存储在同一个代码仓库中。这种方式允许不同项目共享代码和依赖,并在同一个版本控制系统中进行管理。
- MultiRepo(多仓库) :是指将每个项目存储在独立的代码仓库中,每个仓库独立管理代码和依赖。不同项目之间的代码和依赖需要通过包管理工具或其他方式进行共享。
实践指南
全局安装 pnpm
npm install pnpm -g
在项目下面初始化
csharp
pnpm init
得到初始的 package.json
json
{
"name": "versakit-monorepo",
"version": "0.2.2",
"private": "true",
"type": "module",
"scripts": {
"cli:build": "pnpm --filter cli build",
"docs:build": "pnpm --filter docs docs:build",
"docs:dev": "pnpm --filter docs docs:dev",
"docs:preview": "pnpm --filter docs docs:preview",
"ui:build": "pnpm --filter ui build",
"test": "vitest",
"test:ui": "vitest --ui",
"preinstall": "node ./scripts/preinstall.js",
"lint": "eslint packages",
"lint:fix": "eslint packages --fix",
"format": "prettier --write "./**/*.{html,vue,ts,js,json,md}"",
"lint:eslint": "eslint packages/**/*.{ts,vue} --cache --fix",
"prepare": "husky install",
"lint-staged": "lint-staged",
"commitlint": "commitlint --config commitlint.config.cjs -e -V",
"changeset": "changeset",
"packages-version": "changeset version",
"publish": "changeset publish --access=public --registry=https://versakit.npmjs.com/"
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx,vue}": [
"eslint --fix",
"prettier --write",
"git add"
],
"*.{scss,less,styl,html}": [
"prettier --write"
]
},
"dependencies": {
"@types/vue": "^2.0.0",
"@vueuse/core": "^12.0.0",
"eslint": "8",
"sass": "^1.83.0",
"versakit-monorepo": "file:",
"vue": "^3.5.12"
},
"devDependencies": {
"@babel/eslint-parser": "^7.25.9",
"@changesets/cli": "^2.27.11",
"@commitlint/cli": "^19.6.0",
"@commitlint/config-conventional": "^19.6.0",
"@tsconfig/node22": "^22.0.0",
"@types/node": "^22.9.0",
"@types/postcss-pxtorem": "^6.1.0",
"@typescript-eslint/eslint-plugin": "^8.17.0",
"@vitejs/plugin-vue": "^5.1.4",
"@vitest/ui": "^2.1.5",
"@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.20",
"cssnano": "^7.0.6",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.32.0",
"globals": "^15.12.0",
"husky": "^8.0.0",
"jsdom": "^25.0.1",
"lint-staged": "^15.2.10",
"npm-run-all2": "^7.0.1",
"postcss": "^8.4.49",
"postcss-pxtorem": "^6.1.0",
"prettier": "^3.4.2",
"typescript": "~5.6.3",
"vite": "^5.4.10",
"vite-plugin-dts": "^4.3.0",
"vite-plugin-svg-icons": "^2.0.1",
"vitest": "^2.1.5",
"vue-tsc": "^2.1.10"
}
}
当然上面的是经过我整合的好的了
配置Pnpm工作区
- 新建pnpm-workspace.yaml文件,并且写入
makefile
packages:
# 主包,存放所有项目的目录
- "packages/*"
在根目录创建项目

在每个包下面创建package.json文件做单一包管理
以下是项目工程目录

Changesets
什么是Changesets
Changesets 是一种在软件开发和版本控制系统中用于管理代码变更的概念,以下是关于它的详细介绍:
基本定义
- 在版本控制系统如 Git、Mercurial 等中,Changesets 指的是一系列相关的文件修改或变更的集合。它记录了从一个版本到另一个版本之间所发生的所有更改,包括文件的添加、删除、修改等操作。
主要特点
- 原子性:一个 Changeset 通常被视为一个原子操作单元,即要么所有的更改都被应用到版本库中,要么都不应用。这确保了版本库的一致性和完整性。
- 关联性:Changesets 之间存在着一定的关联关系,它们可以形成一个线性的历史记录,也可以通过分支和合并等操作形成复杂的版本树结构。通过这种关联性,可以方便地查看代码的演变过程。
- 可追溯性:每个 Changeset 都有唯一的标识,如 Git 中的哈希值,通过这个标识可以方便地追溯到该 Changeset 所包含的具体更改内容,以及是谁在什么时间进行的修改等信息。
实践指南
1、安装依赖
bash
pnpm install @changesets/cli -wD
2、初始化
csharp
pnpm changeset init
执行完初始化命令后,会在工程的根目录下生成 .changeset
目录
3、在根目录 package.json 中配置对应的命令
json
"scripts": {
"changeset": "changeset",
"packages-version": "changeset version",
"publish": "changeset publish --registry=https://registry.npmjs.com/"
}
执行 pnpm run changeset
1、选择要发布的包

2、发布 minor,选择对应的包
现在是 1.0.0 更新为 1.1.0,这里选择 minor
3、填写 changelog

4、Is this your desired changeset 选择true

执行 pnpm run packages-version

继续发包
不同点在于选择发布 major
,剩余的流程和上面的都一样
Npm私域问题
因为@在Npm上是私人的包
解决方式
在package.json上写入 --access=public

最终结果
