【技巧】优雅的使用 pnpm+Monorepo 单体仓库构建一个高效、灵活的多项目架构

单体仓库(Monorepo)搭建指南:从零开始

单体仓库(Monorepo)是一种将多个相关项目集中管理在一个仓库中的开发模式。它可以帮助开发者共享代码、统一配置,并简化依赖管理。本文将通过实际代码示例,详细介绍如何使用 pnpm 搭建一个单体仓库。

1. 创建项目目录

mkdir xxx && cd xxx
  • mkdir my-monorepo:mkdir 是“make directory”的缩写,用于创建一个新的目录。
  • xxx 是你指定的目录名称,表示要创建一个名为 xxx 的文件夹。例如,你可以将其替换为 my-monorepo,表示创建一个名为 my-monorepo 的目录。
  • &&:这是一个逻辑操作符,表示“并且”。它用于将两个命令连接起来,只有当第一个命令执行成功(返回状态码为0)时,才会执行第二个命令。这是一种快捷方式,可以避免手动切换目录。
  • cd xxx:cd 是“change directory”的缩写,用于切换到指定的目录。xxx 是你刚刚创建的目录名称,表示切换到该目录中。

代码解析:

  • 通过 mkdir && cd 的组合命令,我们可以快速创建并进入项目目录。这一步是搭建任何项目的起点。

    

2. 初始化根目录

pnpm init

    pnpm init 的功能类似于 npm init,用于初始化一个新的 Node.js 项目。它会引导你填写一些基本信息(如项目名称、版本、描述、作者等),并生成一个 package.json 文件。这个文件是项目的配置文件,用于定义项目的依赖、脚本和其他元数据。

代码解析:

  • 运行 pnpm init 后,pnpm 会提示你输入项目的基本信息。如果你不想手动输入,可以使用 pnpm init -y,它会自动填充默认值并生成一个 package.json 文件。

3. 配置工作空间 - 在根目录的 package.json 中添加

{"private": true,  // monorepo 项目需要设置为私有"type": "module",  // 使用 ESM 模块系统"workspaces": ["packages/*"  // 指定工作空间目录]
}
  • “private”: true:将项目设置为私有,避免意外发布到 npm。
  • “type”: “module”:启用 ES 模块系统,允许使用 import/export 语法。
  • “workspaces”:定义工作空间的路径,packages/* 表示所有位于 packages 文件夹中的子项目。

代码解析:

  • 通过配置 workspaces,pnpm 可以识别并管理多个子项目,同时共享依赖和配置。

3.1 创建 packages 目录

mkdir packages
  • 创建一个名为 packages 的目录,用于存放所有子项目。

3.2 创建子项目,例如 editor

mkdir packages/editor
cd packages/editor
  • pnpm init # 初始化子项目的 package.json

    
子项目的 package.json 示例:

{"name": "@my-monorepo/editor",  // 建议使用 @scope 形式命名"version": "1.0.0","private": true,"main": "index.ts","scripts": {"dev": "vite","build": "tsc && vite build","start": "vite"},"dependencies": {// 子项目特定的依赖},"devDependencies": {// 子项目特定的开发依赖},"peerDependencies": {// 如果这是一个库,指定同级依赖"react": "^18.0.0","react-dom": "^18.0.0"}
}

代码解析:

  • “name”: “@my-monorepo/editor”:使用作用域(@scope)命名子项目,可以避免命名冲突。
  • “main”: “index.ts”:指定项目的入口文件。
  • “scripts”:定义项目的开发脚本,例如 dev、build 和 start。
  • “peerDependencies”:如果子项目是一个库,可以通过 peerDependencies 指定同级依赖,例如 react 和 react-dom。

    

4. 常用的工作空间脚本配置

4.1 在根目录安装依赖

pnpm add -w package-name        # 安装生产依赖
pnpm add -w -D package-name     # 安装开发依赖
  • -w:表示在工作空间范围内安装依赖,适用于所有子项目。

4.2 在特定子项目中安装依赖

pnpm add package-name --filter @my-monorepo/editor    # 安装生产依赖
pnpm add -D package-name --filter @my-monorepo/editor # 安装开发依赖
  • –filter:指定在特定子项目中安装依赖。

4.3 在多个子项目中安装依赖

pnpm add package-name --filter "./packages/**"        # 为所有子项目安装依赖
  • –filter “./packages/**”:为所有位于 packages 文件夹中的子项目安装依赖。

4.4 子项目之间的依赖

pnpm add @my-monorepo/shared --filter @my-monorepo/editor  # editor 依赖 shared 包
  • @my-monorepo/shared:子项目之间可以通过 pnpm 直接依赖其他子项目。

注意事项⚠️

子项目版本管理

{"version": "workspace:*"  // 使用工作空间协议,自动同步版本
}
  • “workspace:*”:使用工作空间协议,自动同步所有子项目的版本。

共享配置文件

# 根目录创建共享配置
touch tsconfig.base.json
touch .eslintrc.js
  • tsconfig.base.json:根目录的共享 TypeScript 配置文件。
  • .eslintrc.js:根目录的共享 ESLint 配置文件。

子项目继承配置:

{"extends": "../../tsconfig.base.json","compilerOptions": {"outDir": "./dist","rootDir": "./src"}
}
  • “extends”:子项目通过 extends 继承根目录的共享配置。

常用的开发工具配置:

{"devDependencies": {"typescript": "~5.6.2","vite": "^6.0.5","eslint": "^9.17.0","@types/node": "^22.10.3"}
}
  • 建议安装在根目录:将开发工具安装在根目录,让所有子项目共享相同的开发工具版本。
    项目结构示例
my-monorepo/
├── package.json
├── pnpm-workspace.yaml (可选)
├── tsconfig.base.json
├── .eslintrc.js
├── packages/
│   ├── editor/
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── src/
│   └── shared/
│       ├── package.json
│       ├── tsconfig.json
│       └── src/

解析:
    这样的结构可以让您更好地管理多个相关项目,共享代码和配置,同时保持每个项目的独立性。通过 pnpm 的工作空间功能,你可以轻松地在子项目之间共享依赖和配置,提升开发效率。
在这里插入图片描述希望这篇文章能帮助你快速搭建一个高效、灵活的单体仓库项目!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/67831.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于python的博客系统设计与实现

摘要:目前,对于信息的获取是十分的重要,我们要做到的不是裹足不前,而是应该主动获取和共享给所有人。博客系统就能够实现信息获取与分享的功能,博主在发表文章后,互联网上的其他用户便可以看到,…

Spring Boot AOP实现动态数据脱敏

依赖&配置 <!-- Spring Boot AOP起步依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>/*** Author: 说淑人* Date: 2025/1/18 23:03* Desc…

SparkSQL函数综合实践

文章目录 1. 实战概述2. 实战步骤2.1 创建项目2.2 添加依赖2.3 设置源目录2.4 创建日志属性文件2.5 创建hive配置文件2.6 创建数据分析对象2.6.1 导入相关类2.6.2 创建获取Spark会话方法2.6.3 创建表方法2.6.4 准备数据文件2.6.5 创建加载数据方法2.6.6 创建薪水排行榜方法2.6.…

ElasticSearch DSL查询之排序和分页

一、排序功能 1. 默认排序 在 Elasticsearch 中&#xff0c;默认情况下&#xff0c;查询结果是根据 相关度 评分&#xff08;score&#xff09;进行排序的。我们之前已经了解过&#xff0c;相关度评分是通过 Elasticsearch 根据查询条件与文档内容的匹配程度自动计算得出的。…

《汽车维修技师》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答&#xff1a; 问&#xff1a;《汽车维修技师》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《汽车维修技师》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;北方联合出版传媒&#xff08;…

【中国电信-安全大脑产品介绍】

座右铭&#xff1a;人生的道路上无论如何选择总会有遗憾的&#xff01; 文章目录 前言一、安全大脑介绍二、中国电信-安全大脑产品分类1.防护版2.审计版 三、安全大脑-部署方案总结 前言 安全占据我们日常生活中首要地位&#xff0c;它时时刻刻提醒着我们出入平安。当然网络安…

洛谷P8837

[传智杯 #3 决赛] 商店 - 洛谷 代码区&#xff1a; #include<stdio.h> #include<stdlib.h> int cmp(const void*a,const void *b){return *(int*)b-*(int*)a; } int main(){int n,m;scanf("%d%d",&n,&m);int w[n];int c[m];for(int i0;i<n;…

多线程杂谈:惊群现象、CAS、安全的单例

引言 本文是一篇杂谈&#xff0c;帮助大家了解多线程可能会出现的面试题。 目录 引言 惊群现象 结合条件变量 CAS原子操作&#xff08;cmp & swap&#xff09; 线程控制&#xff1a;两个线程交替打印奇偶数 智能指针线程安全 单例模式线程安全 最简单的单例&…

三分钟简单了解HTML的一些语句

1.图片建议建立一个文件夹如下图所示 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"keywords"><title>魔神羽落</title><style>.testone{background-color: #ff53e…

HCIP笔记4--OSPF域内路由计算

1. 域内LSA 1.1 一类LSA 一类LSA: 路由器直连状态&#xff0c;Router LSA。 串口需要两端配置好IP,才会产生一类LSA; 以太网口只需要一端配置了IP就会直接产生一类LSA。 LSA通用头部 Type: Router 直连路由LS id: 12.1.1.1 路由器router idAdv rtr: 12.1.1.1 通告的路由器&…

k8s基础(7)—Kubernetes-Secret

Secret概述&#xff1a; Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。 由于创建 Secret 可以独立于使用它们的 Pod&#xff0c; 因此在创建、查看和…

【leetcode100】验证二叉搜索树

1、题目描述 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&…

谈谈MySQL中的索引和事务

目录 1. 索引 1.1 索引介绍 1.2 缺陷 1.3 使用 1.3.1 查看索引 1.3.2 创建索引 1.3.3 删除索引 2. 索引底层的数据结构 2.1 B树 3. 事务 3.1 为什么使用事务 3.2 事务的使用 3.3 事务的基本特性 1. 索引 1.1 索引介绍 索引相当于一本书的目录(index), 在一…

2024:CSDN上的收获与蜕变——我的技术成长之旅

2024&#xff1a;CSDN上的收获与蜕变——我的技术成长之旅 前言数据见证&#xff1a;2024年的创作足迹荣誉殿堂&#xff1a;各平台的创作证书与认可社区共建&#xff1a;行业贡献与互动交流展望未来&#xff1a;2025年的目标与计划结语 前言 博主简介&#xff1a;江湖有缘 在技…

博客之星2024年度-技术总结:技术探险家小板的一年的征程

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 技术探险家的新一年征程 2.0 数据库管理与优化&#xff1a;MySQL 的魔法森林 2.1 穿越基础概念的迷雾 2.2 实践应用&#xff1a;成为森林的主人 2.3 性能调优&…

视频m3u8形式播放 -- python and html

hls hls官网地址 创建项目 ts为视频片段 m3u8文件内容 html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" …

【知识分享】PCIe5.0 TxRx 电气设计参数汇总

目录 0 引言 1 参考时钟--Refclk 2 发射端通道设计 3 发送均衡技术 4 接收端通道设计 5 接收均衡技术 6 结语 7 参考文献 8 扩展阅读 0 引言 PCI Express Base Specification 5.0的电气规范中&#xff0c;关键技术要点如下&#xff1a; 1. 支持2.5、5.0、8.0、16.0和3…

【HF设计模式】06-命令模式

声明&#xff1a;仅为个人学习总结&#xff0c;还请批判性查看&#xff0c;如有不同观点&#xff0c;欢迎交流。 摘要 《Head First设计模式》第6章笔记&#xff1a;结合示例应用和代码&#xff0c;介绍命令模式&#xff0c;包括遇到的问题、采用的解决方案、遵循的 OO 原则、…

记一次数据库连接 bug

整个的报错如下&#xff1a; com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Metho…

【游戏设计原理】76 - 惩罚

惩罚是玩家在游戏中得到反馈的一种形式&#xff0c;可以认为是一种负反馈。 除了文中提到的几种惩罚机制&#xff08;“生命/游戏结束/继续”、“枯萎”、“永久死亡”&#xff09;&#xff0c;还有其他一些常见的惩罚类型&#xff0c;它们的设计主要目的是增加游戏的挑战性&a…