夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 微前端

  • 权限控制

  • monorepo

    • pnpm-workspace
    • pnpm-workspace常用命令
      • 名词解释
        • monorepo
        • workspace
      • 在 pnpm 中使用 workspace
        • 项目结构
        • 根目录 package.json
        • pnpm-workspace.yaml
        • 具体语法 - glob 通配符
        • 安装依赖
        • 在根目录中安装依赖
        • 给指定 workspace(工作空间) 安装依赖
        • 更新依赖
        • 执行脚本
        • 安装内部 workspace 依赖
        • 什么是 workspace:^ - semver 版本
        • 总结
  • 《前端架构》
  • monorepo
夜猫子
2024-10-17
目录

pnpm-workspace常用命令

# 名词解释

# monorepo

利用单一仓库来管理多个 packages 的一种策略,如早期的 lerna

# workspace

由上述单仓多包催生的管理方式,workspace(工作空间) 是 npm、yarn、pnpm 等包管理工具提供的一种特性,用于管理多个包的依赖关系。 合理配置 workspace 后,包之间互相依赖不需要使用 npm link,将在 install 时中处理

# 在 pnpm 中使用 workspace

A workspace must have a pnpm-workspace.yaml file in its root. A workspace also may have an .npmrc in its root. 如文档描述,启用 pnpm 的 workspace 需要在项目根目录创建 pnpm-workspace.yaml

# 项目结构

my-monorepo
├── docs
├── apps
│   └── web
├── packages
│   ├── ui
│   ├── eslint-config
│   └── shared-utils
├── pnpm-workspace.yaml
├── .npmrc => optional
└── sdk
1
2
3
4
5
6
7
8
9
10
11

# 根目录 package.json

private: If you set “private”: true in your package.json, then npm will refuse to publish it.

私有化为 true 时,在 publish 时 npm 将不会处理该 package,你可以在项目的根目录配置,或在不需要被 publish 的 workspace 中配置它

{
  "name": "my-monorepo",
  "private": true,
  "script": {
    "dev": "pnpm -r dev"
  }
} 
1
2
3
4
5
6
7

# pnpm-workspace.yaml

在该项目中指定位于 my-monorepo/apps/ 和 my-monorepo/packages/ 内的直接子目录为工作区如 web、ui 等 而 docs 本身则为一个工作区,则不需要通配符

packages:
  - "docs"
  - "apps/*"
  - "packages/*"
1
2
3
4

# 具体语法 - glob 通配符

packages:
  # 选择 packages 目录下的所有首层子目录的包
  - 'packages/*'
  # 选择 components 目录下所有层级的包
  - 'components/**'
  # 排除所有包含 test 的包
  - '!**/test/**'
1
2
3
4
5
6
7

# 安装依赖

/my-monorepo/:

pnpm install
1

# 在根目录中安装依赖

/my-monorepo/:

pnpm add <package-name> -w
# or
pnpm add <package-name> --workspace-root
1
2
3

# 给指定 workspace(工作空间) 安装依赖

/my-monorepo/:

pnpm add <package-name> --filter <workspace-name>
# or
pnpm add lodash --filter docs
1
2
3

# 更新依赖

更新根目录依赖,看执行路径

pnpm update <package-name> [-w]
1

更新指定 workspace 依赖

pnpm update <package-name> --filter <workspace-name>
# or
pnpm update lodash --filter docs
1
2
3

卸载依赖

pnpm uninstall <package-name> [-w]
# or
pnpm uninstall <package-name> --filter <workspace-name>
# or
pnpm uninstall lodash --filter docs
1
2
3
4
5

# 执行脚本

执行 workspace 中的脚本

pnpm dev --filter docs
1

执行所有 workspace 中脚本

pnpm -r dev
# or
$ pnpm --recursive dev
1
2
3

或者在根目录的 package.json 中配置

/my-monorepo/package.json:

{
  "name": "my-monorepo",
  "script": {
    "docs:dev": "pnpm dev --filter docs"
  }
} 
1
2
3
4
5
6

直接执行

pnpm docs:dev
1

# 安装内部 workspace 依赖

pnpm add <package-name> --filter <workspace-name>
# or
pnpm add web --filter docs
1
2
3

笔记

请注意你当前的 pnpm 版本,在 9.0 后 pnpm 修改 link-workspace-packages 的默认值为 false。该属性开启后,你在安装依赖时优先在本地链接,而不是从 registry(远程) 中下载。 所以在这个版本你若需要使用命令安装一个新的 workspace 中的依赖需要在 .npmrc 中启用 link-workspace-packages 当然主动在 package.json 中声明的依赖不受影响,如 web: "workspace:*",pnpm 还是会自动处理,这种不确定性的执行结果可能是导致 pnpm 在该版本中禁用了该值出处。

在 .npmrc 中

.npmrc:

link-workspace-packages = true
1

或临时启用

pnpm add <package-name> --filter <workspace-name> --link-workspace-packages=true
# or
pnpm add web --filter docs --link-workspace-packages=true
1
2
3

执行结果

/my-monorepo/packages/docs/package.json:

{
  "name": "docs",
  "dependencies": {
    "web": "workspace:^"
  }
}
1
2
3
4
5
6

# 什么是 workspace:^ - semver 版本

你可能好奇 workspace:^ 是怎么生成的,后面 pnpm 是怎么如何转化的?

当你将依赖项添加到 package.json 中时,pnpm 根据 .npmrc 或命令行中的 save-workspace-protocol 字段来决定是否使用 workspace: 协议,并根据 save-prefix 字段来决定版本的前缀(semver)

例如,save-prefix 为 "~" ,save-workspace-protocol 为 true 时

{
  "name": "docs",
  "dependencies": {
    "web": "workspace:~1.0.0"
  }
}
1
2
3
4
5
6

转化

{
	"dependencies": {
		"foo": "workspace:*",
		"bar": "workspace:~",
		"qar": "workspace:^",
		"zoo": "workspace:^1.5.0"
	}
}
1
2
3
4
5
6
7
8
{
	"dependencies": {
		"foo": "1.5.0",
		"bar": "~1.5.0",
		"qar": "^1.5.0",
		"zoo": "^1.5.0"
	}
}
1
2
3
4
5
6
7
8

# 总结

# 安装依赖
$ pnpm install

# 给指定 workspace 安装依赖
$ pnpm add <package-name> --filter <workspace-name>

# 卸载依赖
$ pnpm uninstall <package-name> --filter <workspace-name>

# 更新依赖
$ pnpm update <package-name> --filter <workspace-name>

# 给根目录安装依赖 - -w 为安装 -workspace-root
$ pnpm add <package-name> -<D>w

# 内部包的互相引用 - 前提 .npmrc 中配置 link-workspace-packages = true
# 若未配置需手动
$ pnpm add <package-name> --filter <workspace-name>

# 执行 workspace 中的脚本, 或者在根目录的 package.json 中配置
$ pnpm dev --filter docs
# 执行所有 workspace 中的脚本 
$ pnpm -r dev
# or
$ pnpm --recursive dev
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
编辑 (opens new window)
上次更新: 2024/10/17 18:17:38
pnpm-workspace

← pnpm-workspace

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式