乐趣区

关于monorepo:从0开始使用pnpm构建一个Monorepo方式管理的demo

写在后面
Monorepo 这个词你应该不止一次据说了,像 Vue3、Vite、ElementPlus 等优良开源我的项目都是应用 Monorepo 的形式治理我的项目,且这里说到的这几个我的项目都是采纳 pnpm 作为包管理工具。
这篇文章就应用 pnpm 构建一个简略的 Monorepo 形式治理的我的项目。
🍊 什么是 Monorepo?什么是 pnpm?
Q:什么是 Monorepo?
A:Monorepo 是一种项目管理形式,就是把多个我的项目放在一个仓库外面,能够参考神三元大佬的一篇文章:古代前端工程为什么越来越离不开 Monorepo?,这篇文章中介绍了 Monorepo 的概念、收益以及 MulitRepo 的弊病。
Q:什么是 pnpm?
A:pnpm 就是一个包管理工具,原生反对 Monorepo,比 npm 和 yarn 更快一些,其余的能够参考官网和神三元大佬的另一篇文章:为什么当初我更举荐 pnpm 而不是 npm/yarn?
🍌 搞一个 Monorepo 的 demo 玩玩
当初咱们就开始应用 pnpm 来构建一个 Monorepo,在闲事开始之前,你先须要保障你的电脑中具备 Node.js,我的版本的是 16.9.0。
首先你须要有 pnpm 这个工具,装置的话能够从官网找办法,或者间接应用 npm 装置,命令如下:
npm i pnpm -g

当初咱们开始搞事件。
第一步,创立一个我的项目的根目录,这里就叫 monorepo-demo,咋创立都可,这里应用的是命令:
mkdir monorepo-demo

第二步,初始化 package.json,这个没啥说的,命令如下:
pnpm init

这里我对内容做了一点批改,package.json 的内容如下:
{
“name”: “monorepo-demo”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {

"test": "echo \"Error: no test specified\"&& exit 1"

},
“type”: “module”,
“keywords”: [],
“author”: “ywanzhou”,
“license”: “MIT”
}

这里我次要增加了一个 type 字段,这里我应用 ESModule 模块化标准。
第三步,创立 pnpm-workspace.yaml 文件,这个文件定义了工作空间的根目录,内容如下:
packages:

  • ‘packages/ **’

当初咱们就能够在 packages 中创立多个我的项目了,目录构造如下:
monorepo-demo
├── package.json
├── packages
│ ├── components
│ │ ├── index.js
│ │ └── package.json
│ ├── core
│ │ ├── index.js
│ │ └── package.json
│ ├── utils
│ │ ├── index.js
│ │ └── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

第四步,编写每个我的项目的 package.json,其实次要是编写一下名称,不便当前应用,这里我的如下:
{
“name”: “@packages/components”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {

"test": "echo \"Error: no test specified\"&& exit 1"

},
“keywords”: [],
“author”: “”,
“type”: “module”,
“license”: “ISC”,
“dependencies”: {

"lodash": "^4.17.21",
"@packages/utils": "workspace:^1.0.0"

}
}

残余的两个名称别离为 @packages/core 和 @packages/utils。
其实到这根本工作就筹备好了,当初介绍一下如何装置依赖,如何在 packageA 中援用 packageB。
🍋 装置依赖
就这个 demo 来说,咱们如果在根目录下装置依赖的话,这个依赖能够在所有的 packages 中应用,如果咱们须要为具体的一个 package 装置依赖怎么办?
cd 到 package 的所在目录嘛?漏,大漏特漏,咱们能够通过上面这个命令:
pnpm –filter <package_selector> <command>

例如咱们须要在 @packages/components 装置 lodash,命令如下:
pnpm -F @packages/components add lodash

- F 等价于 –filter

当初咱们在往 @packages/utils 中装置一个 dayjs,命令如下:
pnpm –filter @packages/utils add dayjs

🍌 packageA 中援用 packageB
当初咱们就来实现 package 间的互相援用,首先咱们在 @packages/utils/index.js 中写入如下内容:
import dayjs from ‘dayjs’
export function format(time, f = ‘YYYY-MM-DD’) {
return dayjs(time).format(f)
}

而后咱们执行如下命令:
pnpm -F @packages/components add @packages/utils@*

这个命令示意在 @packages/components 装置 @packages/utils,其中的 @* 示意默认同步最新版本,省去每次都要同步最新版本的问题。
装置实现后 @packages/components/package.json 内容如下:
{
“name”: “@packages/components”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {

"test": "echo \"Error: no test specified\"&& exit 1"

},
“keywords”: [],
“author”: “”,
“type”: “module”,
“license”: “ISC”,
“dependencies”: {

"@packages/utils": "workspace: *",
"lodash": "^4.17.21"

}
}

而后咱们在 @packages/components/index.js 写入如下内容:
import {format} from ‘@packages/utils’
console.log(format(new Date()))

而后咱们在我的项目根目录运行如下命令
node packages/components

即可打印出以后的日期。

退出移动版