Monorepo是什么
与Monorepo对比的是MutiRepo
。对于一个复杂的前端架构通常会有多个npm package组成。repo指的是版本仓库。如果多个package放在一个repo仓库中就叫做monorepo。
目前有不少大型开源项目采用了这种方式,如 Babe
l,React
, Meteor
, Ember
, Angula
r,Jest
, Umijs
, Vue
, 还有 create-react-app
, react-router
等。几乎我们熟知的仓库,都无一例外的采用了monorepo 的方式,可以看到这些项目的第一级目录的内容以脚手架为主,主要内容都在 packages目录中、分多个 package 进行管理。
├── packages
| ├── admin # 后台页面
| | ├── package.json
| ├── cms # 前台页面
| | ├── package.json
| ├── server # 服务端
| | ├── package.json
├── package.json
monorepo 最主要的好处是统一的工作流和Code Sharing。比如我想看一个 pacakge 的代码、了解某段逻辑,不需要找它的 repo,直接就在当前 repo;当某个需求要修改多个 pacakge 时,不需要分别到各自的 repo 进行修改、测试、发版或者 npm link,直接在当前 repo 修改,统一测试、统一发版。只要搭建一套脚手架,就能管理(构建、测试、发布)多个 package。
Pnpm实现Monorepo
禁用npm
pnpm 的 monorepo 项目在 node_modules 以及开发中,项目依赖 pnpm workspace 使用 npm 或 yarn 运行时会出现问题。
package.json
"scripts": {
"preinstall": "node ./scripts/preinstall.js"
}
实现当运行 npm install 或 yarn,就会发生错误并且不会继续安装。
if (!/pnpm/.test(process.env.npm_execpath || '')) {
console.log('只能使用pnpm')
console.warn(
`\u001b[33mThis repository requires using pnpm as the package manager ` +
` for scripts to work properly.\u001b[39m\n`
)
process.exit(1)
}
效果
建立工作空间
我们需要配置,让pnpm知道我们这个是单包,包括多个子包
pnpm-workspace.yaml
packages:
# all packages in subdirs of packages/ and components/
- 'packages/**'
依赖安装
# 公共包安装
pnpm i vue -w
# 子package安装
pnpm i vue -r --filter server
# 内部依赖package安装
pnpm i server -r --filter admin
依赖安装
# 安装在root下
pnpm i dayjs -w
# 安装在ui下
pnpm i dayjs