pnpm

yuhuo2023-09-21JavaScriptNodeJs
参考链接

前言

pnpm 主要解决 npm 和 yarn 遗留的问题:

  • 幽灵依赖:A 依赖 B,B 依赖 C,A 没有直接依赖 C 却可以引用 C;
  • 依赖分身:A 依赖 B@1、C 和 D,同时 C 和 D 依赖 B@2,那 B@2 就会在 C 和 D 的模块下重复安装;

pnpm 引入了另一套依赖管理策略:内容寻址存储

该策略会将包安装在系统的全局 store 中,依赖的每个版本只会在系统中安装一次。

在引用项目 node_modules 的依赖时,会通过硬链接与符号链接在全局 store 中找到这个文件。为了实现此过程,node_modules 下会多出 .pnpm 目录,而且是非扁平化结构。

node_modules
├── .pnpm
│   ├── A@1.0.0
│   │   └── node_modules
│   │       ├── A => <store>/A@1.0.0
│   │       └── B => ../../B@1.0.0
│   ├── B@1.0.0
│   │   └── node_modules
│   │       └── B => <store>/B@1.0.0
│   ├── B@2.0.0
│   │   └── node_modules
│   │       └── B => <store>/B@2.0.0
│   └── C@1.0.0
│       └── node_modules
│           ├── C => <store>/C@1.0.0
│           └── B => ../../B@2.0.0
│
├── A => .pnpm/A@1.0.0/node_modules/A
└── C => .pnpm/C@1.0.0/node_modules/C

pnpm 也存在一些弊端:

  • 在不支持软链接的环境中,无法使用 pnpm,比如 Electron 应用;
  • 不同项目的依赖是硬链接到同一份文件,如果在调试时修改了文件,有可能会无意中影响到其他项目;

安装

npm install yarn -g

-v

# 查看 pnpm 版本
pnpm -v

config

# 配置 pnpm 全局包目录
pnpm config set global-dir "D:\Software\NodeJs\pnpm\global"

# 配置 pnpm 全局包的 bin 目录(还需要将该目录添加到环境变量 Path 中)
pnpm config set global-bin-dir "D:\Software\NodeJs\pnpm\global_bin"

# 配置 pnpm 全局存储目录(项目包的实际存储位置)
pnpm config set store-dir "D:\Software\NodeJs\pnpm\store" 

# 配置 pnpm 缓存目录
pnpm config set cache-dir "D:\Software\NodeJs\pnpm\cache"

# pnpm-state.json文件目录
pnpm config set state-dir "D:\Software\NodeJs\pnpm\state" 

# 配置仓库路径 
# 默认仓库 https://registry.npmjs.org 下载缓慢,可以改为淘宝镜像仓库
npm config set registry https://registry.npmmirror.com

# 查看当前配置
npm config list

# 查看指定配置
npm config get <configName>
# 删除指定配置
npm config delete <configName>

init

# 直接创建默认 package.json
pnpm init

run

# 查看 pakage.json 下的所有 scripts 脚本
pnpm run
# 运行指定 scripts 脚本
pnpm run <task-name>
# run 可以直接省略
pnpm <task-name> 

install

# 全局包,安装至全局包目录下的 node_modules,可全局使用对应命令行
pnpm install <name> -global 
# npm 也可以安装不同版本 npm
pnpm install npm -global

# (注:项目包,统一安装至当前目录下的 node_modules 文件夹)
# 安装 package.json 里的指定版本的所有包,生成 workspaces 字段指定的子包软链接
pnpm install
# (注:安装时已存在不同版本会覆盖,相同版本不处理)
# 运行依赖包安装,写入 package.json 的 dependencies 字段
pnpm install <name> 
pnpm install <name>  --save 
# 开发依赖包安装,写入 devDependencies 字段
pnpm install <name>  --save-dev

# 安装无标签最高版本的包
pnpm install <name>
# 安装指定版本的包
pnpm install <name>@<version>
# 安装指定标签最高版本的包
pnpm install <name>@<tag>

简写

  • install => i
  • --global => -g
  • --save => -S
  • --save-dev => -D

uninstall

# 卸载指定包
yarn uninstall <name>  

list

# 查看当前项目包依赖
npm list  
# 查看全局包依赖
npm list -g
# 查看指定包
npm list <name>  

简写

  • list => ls
  • --global => -g

info / view / show

查看 npm 仓库包

# 查看详细信息
pnpm info <name>
pnpm view <name>
pnpm show <name>

# 查看最新版本
pnpm info <name> version
pnpm view <name> version
pnpm show <name> version

# 查看历史版本
pnpm info <name> versions
pnpm view <name> versions
pnpm show <name> versions

简写

  • view => v

outdated / update

# 查看需要更新的包
pnpm outdated
# 更新所有需要更新的包
pnpm update
# 更新指定包
pnpm update <name>  

publish / unpublish

# 发布包
pnpm publish
# 发布带自定义标签名的包
pnpm publish --tag beta
# 发布 @name/package 类型的包,默认是私有包,需要指定为公开包
pnpm publish --access public

# 卸载当前项目version字段指定版本的发布包
pnpm unpublish --force
// package.json
{
    // commonjs模块类型的入口文件,被 require('moduleName') 时加载
	"main": "dist/index.js",  
    
    // module模块类型的入口文件,被 import xx from 'moduleName' 时加载
    "module": "dist/index.js",  
    
    // npm发布的文件白名单
    "files": [  
        "dist"
    ],
} 

store

# 从存储中删除未被引用的包
pnpm store prune

# 查看存储中被过修改的包
pnpm store status

# 查看存储的路径
pnpm store path

# 往存储中添加一个包
pnpm store add <name>

monorepo

在根目录下配置 pnpm-workspace.yaml 文件,标志当前项目为 monorepo 项目。

packages:
  - "packages/*"

在 A 子包中引用了 B 子包,也需要在 A 子包中像对其他第三方包一样安装和引用 B 子包。此时 A 子包的 node_modules 中就会出现 B 子包的软链接。

同时在引用时,TS 会报路径错误,需要配置一下 tsconfig.json 文件:

{
    "compilerOptions": {
        "paths": {
            	// 假设子包都是 @yho-vue/ 开头,
                // 引用到子包时,则映射到对应文件夹 src 目录
                "@yho-vue/*": ["./packages/*/src"]
            }
        },
}

安装命令

# 在根目录安装依赖包
pnpm install <name> --workspace-root

# 指定子包安装依赖包(或者直接进入子包中,正常安装无须参数)
pnpm install <name> --filter <son-package>
# 在所有子包安装依赖
pnpm install <name> --filter *

# 其他操作(如 uninstall)也是相同参数,不再列举

简写

  • --filter => -F
  • --workspace-root => -w
Last Updated 2024/3/14 09:51:53