当前位置: 首页 > ai >正文

项目改 pnpm 并使用 Monorepo 发布至 npm 上

相关概念

pnpm:
pnpm (Performant npm) 是一个快速、节省磁盘空间的 Node.js 包管理器,与 npmYarn 兼容但采用了不同的依赖管理方法。

  • 全局存储:所有依赖只保存一份在 ~/.pnpm-store
  • 硬链接技术:项目中 node_modules 只是指向全局存储的链接
  • 实际效果:相比 npm/Yarn 可节省 60-70% 的磁盘空间
  • 典型项目安装速度比 npm 快 2倍 以上
  • 解决幽灵依赖问题:无法引用未在 package.json 的依赖

Monorepo:
Monorepo(单一代码仓库)是一种软件开发策略,指的是将多个相关项目或包的代码存储在同一个版本控制仓库中,而不是为每个项目或组件使用单独的仓库。

将 npm 项目迁移到 pnpm

  1. 安装 pnpm
    npm i pnpm -g
    
    查看是否安装成功及版本号
    pnpm -v
    
  2. 基本迁移
    • 删除 npm 的锁定文件和 node_modules
    rm -rf node_modules package-lock.json
    
    • 使用 pnpm 安装依赖:
    pnpm install
    
    这会创建 pnpm-lock.yaml 文件代替 package-lock.json
  3. 更新 package.json 脚本
    • 将 npm 命令替换为 pnpm
    {"scripts": {"dev": "pnpm run dev",  // 原先是 npm run dev"build": "pnpm run build"}
    }
    

改造为 Monorepo

1. 配置工作区

  • 在项目根目录创建 pnpm-workspace.yaml
    packages:- 'packages/*'
    
      配置:- `packages/*`       - 存放共享的库/包- `!**/__tests__`    - 排除测试目录
    
  • 或者在 package.json 中添加
    {"private": true,  // monorepo 项目需要设置为私有"type": "module",  // 使用 ESM 模块系统"workspaces": ["packages/*"  // 指定工作空间目录]
    }
    
      两种选一种配置即可,	如果同时存在 package.json 的 workspaces 和 pnpm-workspace.yaml:pnpm-workspace.yaml 优先级更高,pnpm 会忽略 package.json 的 workspaces 配置。
    

2. 创建子包

创建共享库包

在根目录下创建 packages 目录,以及子包的目录:task-processorthread-poolshared
进入这两个目录中分别执行命令:

pnpm init

编辑生成的 package.jsonname

{"name": "@my-monorepo/shared","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC"
}

3. 安装依赖

  • 安装全局依赖(所有包共享)

    pnpm add -D -w typescript vite @types/node
    # 或
    pnpm add -Dw typescript vite @types/node
    

    -D 表示开发依赖,没有则是生产依赖
    -w 表示 在 Monorepo 的根目录(工作区根目录)执行操作,而不是在某个具体的子包中执行。

  • 安装 packages 的子包的依赖

    pnpm add moment --filter @my-monorepo/thread-pool
    pnpm add lodash --filter @my-monorepo/task-processor
    

    --filter:指定在特定子项目中安装依赖。

  • 子包之间相互依赖

    pnpm add @my-monorepo/shared@workspace:* --filter @my-monorepo/thread-pool
    

    workspace:* 表示总是使用工作区内的最新版本

    4. 常用命令

    • 在所有包中运行命令
      pnpm -r run build
      
      -r 表示递归执行
    • 在特定包中运行命令
      pnpm --filter @my-monorepo/web run dev
      
    • 安装所有依赖
      pnpm install
      

5. 高级配置

共享配置

可以在根目录创建共享的配置文件(如 tsconfig.base.json),然后在各包中继承:

{"extends": "../../tsconfig.base.json","compilerOptions": {"outDir": "./dist"}
}

限制依赖版本

在根目录 package.json 中添加:

{"pnpm": {"overrides": {"react": "18.2.0","typescript": "^4.9.0"}}
}

版本管理、发布

安装并初始化 Changesets

pnpm add -Dw @changesets/cli
pnpm changeset init

这会创建 .changeset 目录和配置文件。

流程

  1. 添加变更说明

    pnpm changeset
    

    交互式命令行会引导您:

    • 选择要版本化的包

    • 选择版本更新类型 (major/minor/patch) 【未选中时,点击回车切换更新类型】

    • 编写变更描述

      这会生成一个 changeset 文件在 .changeset 目录中。

  2. 版本升级

    pnpm changeset version
    

    这个命令会:

    • 根据 changeset 文件更新包版本
    • 更新依赖关系
    • 生成 CHANGELOG.md 文件
    • 删除已处理的 changeset 文件
  3. 发布到 npm
    在各个子包的 package.json 中添加:

      "publishConfig": {"access": "public","registry": "https://registry.npmjs.org/"}
    

    否则会报错:402 Payment Required - PUT https://registry.npmjs.org/xxx - You must sign up for private packages

    然后需要在 npm 中创建对应的 组织
    在这里插入图片描述
    然后执行命令:

    	nrm use npmnpm loginpnpm changeset publish
    

    npm login 前需要切换至 npm 源,不能使用 cnpm 或者 taobao 等源;
    扩展:在 git 中设置并提交对应的 tag 为此次的版本发布

http://www.xdnf.cn/news/4425.html

相关文章:

  • ChatGPT-4o:临床医学科研与工作的创新引擎
  • SQL 子查询
  • 深入浅出理解常见的分布式ID解决方案
  • 理解网站导航文件:robots.txt、sitemap.xml与LLMs.txt的全面解析
  • 控制mac地址表端口安全
  • 前端面经-VUE3篇(四)--pinia篇-基本使用、store、state、getter、action、插件
  • 【免费】2003-2018年全国各地级市进出口总额数据
  • Nginx 性能调优与深度监测全攻略
  • AI——认知科学中的认知架构建立步骤与方法
  • 【Prometheus】业务指标与基础指标的标签来源差异及设计解析(扩展版)
  • oracle 数据库sql 语句处理过程
  • LeetCode 热题 100_最长回文子串(93_5_中等_C++)(暴力破解法;动态规划)
  • LLaMA-Factory微调DeepSeek-R1-Distill-Qwen-7B
  • 2025年数字藏品行业DDoS攻防指南:技术升级与合规防御双轨制
  • 【C++】类和对象【下】
  • MySQL 中的 MVCC 是什么?
  • SRAM详解
  • vscode 安装插件
  • 软件开发模型介绍
  • MATLAB制作直方图
  • 【25软考网工】第五章(8)路由协议RIP、OSPF
  • QT聊天项目DAY09
  • 【神经网络与深度学习】VAE 中的先验分布指的是什么
  • 嵌入式音视频通话EasyRTC基于WebRTC技术驱动智能带屏音箱:开启智能交互新体验
  • MySQL从入门到精通(三):MySQL数据类型、SQL语言—DDL
  • 老年综合评估实训室虚拟仿真建设的关键技术与发展路径
  • 【论文阅读】Towards Stable Backdoor Purification through Feature Shift Tuning
  • C++ 完美转发
  • k8s部署OpenELB
  • vue3父组件调用子组件方法