使用pnpm workspace管理Monorepo架构
在开发项目的过程中,我们需要在一个仓库中管理多个项目,每个项目有独立的依赖、脚手架,这种形式的项目结构我们称之为Monorepo
,pnpm workspace
就是管理这类项目的方案之一。
一、pnpm简介
1、pnpm概述
pnpm
代表performance npm
(高性能的npmn
),同npm
和yarn
,都属于javascript
包管理安装工具,它较npm
和yarn
在性能上得到很大提升,被称为 快速地,节省磁盘空间的包管理工具。
2、pnpm优点
-
快速:pnpm会将包缓存到本地,减少二次安装需要的时间。
-
节省磁盘空间:他会把包软链到项目本地,不需要反复安装。
-
节省网络带宽:同样的道理
-
更好的依赖处理逻辑
3、对比lerna+yarn
使用lerna+yarn
组合,也可以实现Monorepo
项目管理。但是相比来说,更推荐pnpm workspace
来管理。
原因如下:
当使用npm
和yarn
时,如果你有100个项目使用了某个依赖,就会有100份该依赖的副本保存在硬盘上,而在使用pnpm
时,依赖会被存储在内容可寻址的存储中。
-
如果你用到了某依赖项的不同版本,只会将不同版本间有差异的文件添加到仓库。 例如,如果某个包有100个文件,而它的新版本只改变了其中1个文件。那么
pnpm update
时只会向存储中心额外添加1个新文件,而不会因为仅仅一个文件的改变复制整新版本包的内容。 -
所有文件都会存储在硬盘上的某一位置。 当软件包被安装时,包里的文件会硬链接到这一位置上对应的文件,而不会占用额外的磁盘空间。 这允许你跨项目地共享同一版本的依赖。
4、安装pnpm
如果已经安装了npm
,直接使用npm i -g pnpm
进行全局安装。
二、构建一个Monorepo项目
先上最终的项目结构:
Monorepo
- umi-antd
- web
-- common1
-- common2
如上图,我们最终要创建如上图的一个项目结构,其中umi-antd
是主项目,web
文件夹下的都是子项目,供umi-antd
调用。
1、创建主项目
主项目这里是使用的umi
项目,这里也可以构建基于其他打包工具的各类项目,只要是遵守package.json
配置条例的项目,都是可以的。
构建umi项目
pnpm dlx create-umi@latest
这里选择创建Ant Design Pro
项目。
$ npx create-umi@latest
? Pick Umi App Template › - Use arrow-keys. Return to submit.Simple App
❯ Ant Design ProVue Simple App
2、创建子项目common1
-
进入
Monorepo>web
目录,创建common1
文件夹 -
然后进入
common1
目录,执行命令npm init
对项目进行初始化,这时候会生产一个package.json
文件 -
新建
index.ts
文件,代码如下:export default function print(msg:string) {console.log(msg); }
3、创建子项目common2
步骤和创建common1
一致
4、主项目中引入子项目
安装common1
和common2
。
pnpm -F umi-antd add common1
pnpm -F umi-antd add common2
安装完成后,在umi-antd
依赖中出现两个子项目的软链接(或者叫符号链接)。
在业务代码中调用子项目输出的方法:
//umi-antd\src\pages\Home\index.tsximport Guide from '@/components/Guide';
import { trim } from '@/utils/format';
import { PageContainer } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import styles from './index.less';
import print1 from 'common1';
import print2 from 'common2';const HomePage: React.FC = () => {const { name } = useModel('global');print1("umi-antd中调用common1");print2("umi-antd中调用common2");return (<PageContainer ghost><div className={styles.container}><Guide name={trim(name)} /></div></PageContainer>);
};export default HomePage;
5、运行主项目
到这里基本搭建完毕,这时候的整体项目结构如图:
然后执行命令启动主项目:pnpm -F umi-antd start
,我们可以看到,控制台打印出来子模块中的信息。
6、子模块调用子模块
子模块也是可以相互调用的,这里我们在common1
中引入common2
的方法。
-
执行命令
pnpm -F common1 add common2
-
在
common1
中调用common2
中方法,代码如下://web\common1\index.ts import print2 from 'common2'; export default function print(msg:string) {console.log(msg);print2("这里是common1中调用common2"); }
再次运行umi-antd
项目时,我们可以看到,控制台已经打印了common2
中方法。
三、workspace协议(workspace:)
1、协议概述
默认情况下,如果可用的 packages 与已声明的可用范围相匹配,pnpm 将从工作区链接这些 packages。 例如, 如果bar
引用"foo": "^1.0.0"
并且foo@1.0.0
存在工作区,那么pnpm会从工作区将foo@1.0.0
链接到bar
。 但是,如果 bar
的依赖项中有 "foo": "2.0.0"
,而 foo@2.0.0
在工作空间中并不存在,则将从 npm registry 安装 foo@2.0.0
。 这种行为带来了一些不确定性。
幸运的是,pnpm 支持 workspace 协议 workspace:
。 当使用此协议时,pnpm 将拒绝解析除本地 workspace 包含的 package 之外的任何内容。 因此,如果您设置为 "foo": "workspace:2.0.0"
时,安装将会失败,因为 "foo@2.0.0"
不存在于此 workspace 中。
当 link-workspace-packages 选项被设置为 false
时,这个协议将特别有用。 在这种情况下,仅当使用 workspace:
协议声明依赖,pnpm 才会从此 workspace 链接所需的包。
以上是官网的解释,实际在使用的时候,如果引入的项目需要强制使用本地包,则可以使用workspace:
协议。改造下umi-antd
的package.json
文件如下:
"dependencies": {"@ant-design/icons": "^5.0.1","@ant-design/pro-components": "^2.4.4","@umijs/max": "^4.0.76","antd": "^5.4.0","common1": "workspace:^","common2": "workspace:^"},
上面加上common1
和common2
的依赖声明后,会强制到本地寻找,找不到也不会到npm registry
对应的私仓去下载。
2、版本符号
workspace协议,区分*
、~
、^
、版本号
,表示的意义各部相同,具体如下:
{"dependencies": {"foo": "workspace:*","bar": "workspace:~","qar": "workspace:^","zoo": "workspace:^1.5.0"}
}
///将会被转化为:
{"dependencies": {"foo": "1.5.0","bar": "~1.5.0","qar": "^1.5.0","zoo": "^1.5.0"}
}
workspace协议官方说明:官方地址
相关文章:

使用pnpm workspace管理Monorepo架构
在开发项目的过程中,我们需要在一个仓库中管理多个项目,每个项目有独立的依赖、脚手架,这种形式的项目结构我们称之为Monorepo,pnpm workspace就是管理这类项目的方案之一。 一、pnpm简介 1、pnpm概述 pnpm代表performance npm…...

Ubuntu16.04-ros-kinetic环境搭建笔记=1=
tips:搬运资料,留个记录 安装Ubuntu Ubuntu官网下载地址 安装 虚拟机安装Ubuntu 最好断网安装Ubuntu,可以节约时间 Ubuntu基础设置 Ubuntu换国内源 换成清华源 sudo apt upgradeVMwareTool安装 把这个压缩包拖到桌面,否则只读…...

应用层自定义协议(组织数据的格式)
概念 在进行网络传输数据的时候,通常是将要传输的数据组织成一个字符串,再将字符串转换为一个字节流进行网络传输数据,而数据组织的格式是多种多样的,我们只需要保证,客户端和服务器对于字符串的组织和解析统一即可 现…...

5种常见的3D游戏艺术风格及工具栈
在游戏开发领域,3D 艺术风格已成为为玩家创造身临其境、引人入胜的体验的重要组成部分。 随着技术的进步,创造令人惊叹的 3D 视觉效果的可能性已经大大扩展,为游戏开发人员提供了广泛的选择。 在本文中,我们将探讨当今游戏开发中…...

【玩转Linux操作】crond的基本操作
🎊专栏【玩转Linux操作】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Counting Stars 】 欢迎并且感谢大家指出小吉的问题🥰 文章目录 🍔概述🍔命令⭐常用选项 🍔练…...
设置Linux 静态IP
LInux虚拟机默认的IP地址是动态获取的 作为服务器,我们一般还需要把IP地址设置为静态的 设置静态IP vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno # BOOTPROTOdhcp 动态获取 BOOTPROTOstatic IPADDR"192.16…...

JMeter接口自动化测试实例—JMeter引用javaScript
Jmeter提供了JSR223 PreProcessor前置处理器,通过该工具融合了Java 8 Nashorn 脚本引擎,可以执行js脚本以便对脚本进行前置处理。其中比较典型的应用就是通过执行js脚本对前端数据进行rsa加密,如登录密码加密。但在这里我就简单的应用javaScr…...

javascript期末作业【三维房屋设计】 【源码+文档下载】
1、引入three.js库 官网下载three.js 库 放置目录并引用 引入js文件: 设置场景(scene) (1)创建场景对象 (2)设置透明相机 1,透明相机的优点 透明相机机制更符合于人的视角,在场景预览和游戏场景多有使用…...

数组详解
1. 一维数组的创建和初始化 1.1 数组的创建 数组是一组相同类型元素的集合。 数组的创建方式: type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式,用来指定数组的大小 数组创建的实例: //代码1 int a…...
【记录COCO数据集格式】实例分割的annotations.json的内部格式
在此记录一下实例分割coco的annotations.json的格式 annotations.json,整体是一个字典: { "info": {"description": null,"url": null, "version": null, "year": 2023, "contributor": null, "date_created…...
mac 关于获取手机信息 终端指令
iOS真机命令(自动化测试) 获取设备的的UDID idevice_id --list # 显示当前所连接设备的 udid instruments -s devices # 列出所有设备,包括真机、模拟器、mac ideviceinfo 可以在返回的数据中找到 udid idevice_id -l 苹果手机 safari打开网…...
ios消息推送例子
通过Apple推送服务,将消息发送给特定的ios客户端,这是服务器端实例代码。需要客户端的voip key值,以及相应的客户端回调接口,支持ios9.0以上版本。 下载地址:https://download.csdn.net/download/m0_37567738/8821559…...

LabVIEW开发最小化5G系统测试平台
LabVIEW开发最小化5G系统测试平台 由于具有大量存储能力和数据的应用程序的智能手机的激增,当前一代产品被迫提高其吞吐效率。正交频分复用由于其卓越的品质,如单抽头均衡和具有成本效益的实施,现在被广泛用作物理层技术。这些好处是以严格的…...

如何用输入函数为数组赋值
在编写程序时我们经常使用数组,而数组的大小可能是很大的但是我们并不需要为每个元素都自己赋值,我们可能会自定义输入数组元素个数,我们应该如何实现通过输入函数为数组赋值呢? 目录 第一种: 第二种: 第一…...
【Python COM】Word 自动纵向合并相同内容单元格
使用场景 docxtempl 库不支持动态纵向合并单元格,所以写了这段代码用来曲线救国。 使用方法 需要纵向合并的单元格加上在文本末尾加上“【纵向合并】”,然后调用此函数,就会自动纵向合并相同内容的单元格。 代码 需要安装 pywin32 库。 …...
maven 环境变量的配置
1、安装好maven /home/sunyuhua/dev/apache-maven-3.9.32、编辑环境变量 vi /etc/profile.d/maven.shexport MAVEN_HOME/home/sunyuhua/dev/apache-maven-3.9.3 export PATH$PATH:$MAVEN_HOME/bin3、执行source source /etc/profile4、检验 mvn -version5、附注:…...
flutter-设置开屏页 解决开屏白屏问题
flutter_native_splash 当您的应用程序打开时,本机应用程序会短暂加载 Flutter。默认情况下,在此期间,本机应用程序会显示白色启动屏幕。该包自动生成 iOS、Android 和 Web 本机代码,用于自定义本机启动画面背景颜色和启动图像。支…...

简单理解Linux中的一切皆文件
一款操作系统要管理各种各样不同的硬件,因为硬件的不同所以它们使用的文件系统也不同。但是按道理来说,文件系统的不同对于用户来说可不是一件好事,操作不同的硬件就要使用不同的方法。 但是Linux有一切皆文件。 简单来说,Linux…...

Kubernetes的endpoint
简介 Kubernetes的endpoint(终结点)是用于将服务绑定到集群中其他组件的网络地址。Endpoint为服务提供了一个稳定的虚拟IP地址,它会负责将流量从Service路由到后端Pod。 下面是使用Kubernetes的endpoint的详细步骤: 创建一个Se…...
第四章,向量组,2-矩阵等价与向量组等价的关系
第四章,向量组,2-矩阵等价与向量组等价的关系 矩阵乘法与线性表示矩阵等价与向量组等价 玩转线性代数(23)线性组合与线性表示的应用的笔记,相关证明以及例子见原文 矩阵乘法与线性表示 设有 A m ∗ n B n ∗ l C m ∗ l A_{m*n}B_{n*l}C_{m…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...