使用pnpm包管理器替代npm及yarn的命令示例

目录
  • 前言
  • 为什么会有 pnpm
  • 不止于此
    • 什么是扁平化的 node_modules
    • pnpm 的 node_modules
  • 如何使用 pnpm
    • 安装
      • 直接安装
      • 通过 npm 安装
      • 通过 HomeBrew 安装( 一种 MacOS 包管理器)
    • 升级
    • 使用
      • 配置
      • 命令
      • 和其他包管理器比较
  • Monorepo 及 工作空间(Workspace)
    • 什么是 Monorepo
    • Workspace
      • workspace: 协议
  • 结语

前言

今天给大家介绍一种新的包管理器:pnpm,pnpm 由 zkochan 开发,最初也是在用 npm 或者 yarn 遇到了一些不爽的地方,于是自己做了一个开源的包管理器,也为优化包管理提供了一种不同的新思路,接下来我们就看一下为何要使用 pnpm,以及他能做什么

值得一提的是,zkochan 也是一名乌克兰的开发者,他也在主页呼吁大家援助一下乌克兰,我也希望当前的国际局势能更快的稳定下来,不要损失这么优秀的开发者

为什么会有 pnpm

一句话概括就是:节约磁盘空间并提升安装速度

设想一下,假如公司的每个项目都用了 vue 全家桶,那么每个项目都需要安装 vue、vue-router、vuex、axios 等几乎相同的库,如果有 100 个项目,那就要重复安装 100 遍!!,要知道,现如今,硬盘虽然便宜,但也没那么多插槽啊,更别说笔记本电脑这寸土寸金的资源空间。

因此,pnpm 的核心就是将所有的包都存放在一个资源仓库中,而每个项目的 node_modules 通过软链接的形式将包链接到资源仓库中,这样不仅节省了空间,同时也加快了安装速度

不止于此

pnpm 的另一个优点,在保留了非扁平化的 node_modules 文件夹,同时节省了空间

什么是扁平化的 node_modules

我们简单回顾一下 npm 的发展历史

1.最初,npm 只是简单的通过依赖去递归的安装包,所有的依赖放在相应的包文件夹下面,假如 A 依赖了 foo,B 也依赖了 foo,那么就会有两份 foo 安装在 node_modules

node_modules
├── A
│   └── node_modules
│       └── foo
└── B
    └── node_modules
        └── foo

2.经过一次优化, npm 为了节省空间,采用了扁平化的 node_modules,这样,假如 A 和 B 都依赖了 foo,那么 foo 会提升至顶层,也就是说 node_modules 文件夹里的包会变成 A、B、foo

node_modules
├── A
├── B
└── foo

这样的好处是,同一个包 foo 只会有一份,节省了空间,但是引入了一个新的问题,引用混乱!!。

试想一下,我们的项目依赖本来只有 A 和 B,假如你想 import foo,肯定是找不到的,但是扁平化的结果,将 A 和 B 的依赖层级提升到了顶级,这样,我们直接引用 foo,其实也不会报错,但实际上我们并没有指定依赖 foo,导致了使用上的混乱,假如有一天,A 和 B 都不依赖于 foo 了,那我们的项目或者说我提供的包就会报错

这个不良的行为其实已经默默的融入我们的开发中,当我们使用 ant-design 时,我们可以直接使用 moment,当我们使用 axios 时,我们可以直接使用 qs,当我们使用 webpack 时,我们可以直接使用 lodash,而无需额外的安装包

pnpm 的 node_modules

假设我们的项目依赖 foo 包,而 foo 又依赖 bar 包,那么 pnpm 安装后的实际 node_modules 结果如下

node_modules
├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
└── .pnpm
    ├── bar@1.0.0
    │   └── node_modules
    │       └── bar -> <store>/bar
    └── foo@1.0.0
        └── node_modules
            ├── foo -> <store>/foo
            └── bar -> ../../bar@1.0.0/node_modules/bar

我们分析一下这个目录结构

  • 包都是从 store 软链接而来
  • 项目直接使用的包只有一个 foo,保证了只有依赖项中的包才能访问
  • 有个隐藏的文件夹 .pnpm,这里将所有的依赖进行扁平化,这样避免了循环符号链接,同时 foo 还能引用自己

如果添加 qar@2.0.0 作为 bar 和 foo 的依赖项,那么结果会变成

node_modules
├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
└── .pnpm
    ├── bar@1.0.0
    │   └── node_modules
    │       ├── bar -> <store>/bar
    │       └── qar -> ../../qar@2.0.0/node_modules/qar
    ├── foo@1.0.0
    │   └── node_modules
    │       ├── foo -> <store>/foo
    │       ├── bar -> ../../bar@1.0.0/node_modules/bar
    │       └── qar -> ../../qar@2.0.0/node_modules/qar
    └── qar@2.0.0
        └── node_modules
            └── qar -> <store>/qar

如何使用 pnpm

安装

直接安装

curl -fsSL https://get.pnpm.io/install.sh | PNPM_VERSION=7.0.0-rc.2 sh -

或者

wget -qO- https://get.pnpm.io/install.sh | PNPM_VERSION=7.0.0-rc.2 sh -

通过 npm 安装

npm install -g pnpm@next-7

通过 HomeBrew 安装( 一种 MacOS 包管理器)

brew install pnpm

升级

简单的通过 pnpm 自己的命令升级即可

pnpm add -g pnpm

使用

配置

大部分配置可以直接使用 npm 的配置,与之区别的是有些配置可能是 pnpm 专有的,例如:

# 配置仓库路径
pnpm config set store-dir /path/to/.pnpm-store

命令

安装依赖

pnpm install
# 其他一些参数
--offline   仅从 store 中离线下载
--dev, -D   只下载 devDependencies 依赖
--frozen-lockfile  不会生成 lockfile
--shamefully-hoist 创建扁平结构,类似于 npm ,不推荐

2. 增加依赖

pnpm add <pkg>

这里 pnpm 有多种增加方式

  • 直接通过配置的源安装

在 workspace 中,会先检查 workspace 是否有相应包,至于 workspace 是什么,在下面会详细说道

从本地安装: 例如你想调试开发的包时

pnpm add ./package.tar.gz
pnpm add ./some-directory

从远端安装 Tar 包

pnpm add https://github.com/indexzero/forever/tarball/v0.5.6

从 git 安装

pnpm add <git remote url>
# 其他一些参数
--save-dev, -D	安装为 devDependencies,也就是开发环境使用的包
--save-peer  	安装为 peerDependencies ,同时安装到 devDependencies, peerDependencies 通常是和该包一起使用的其他包,需要使用者同时下载
--global, -g	安装为全局依赖

发布依赖

pnpm [-r] publish [&lt;tarball|folder&gt;] [--tag &lt;tag&gt;]
     [--access &lt;public|restricted&gt;] [options]
--no-git-checks	不检查当前分支是否是可发布分支,是否有没有提交的代码,直接发布
--dry-run	执行发布包的所有流程,但唯独不会真正把包发布到源上,这个在测试发布的时候非常有用
-r		递归的执行发布命令,通常在 workspace 中使用

这里只列出常用的一些,更多的命令可以参考官网

和其他包管理器比较

npm 命令 pnpm 等效
npm install pnpm install
npm i [pnpm add ]
npm run [pnpm ]
功能 pnpm Yarn npm
工作空间支持(monorepo)
隔离的 node_modules ️ - 默认
提升的 node_modules ️ - 默认
Plug'n'Play ️ - 默认
零安装
修补依赖项
管理 Node.js 版本
有锁文件 ️ - pnpm-lock.yaml ️ - yarn.lock ️ - package-lock.json
支持覆盖 ️ - 通过 resolutions
内容可寻址存储
动态包执行 ️ - 通过 pnpm dlx ️ - 通过 yarn dlx ️ - 通过 npx

Monorepo 及 工作空间(Workspace)

什么是 Monorepo

Monorepo 由两个单词组成,Mono 指的是单个(single),repo 指的是项目存储(Repository),合起来意思就是说,大量的项目存储在单一的库中,用人话讲就是,不同的项目都写在一个 git 库里,第一次听到这个概念的时候大家肯定觉得这人指定有什么大病,这么多项目放一起,大家在里面各种修改,一个人项目修改了,另一个不相干的项目肯定还得更新代码,这不是技术倒退么,这个其实还真就是 Monorepo 的缺点,但是静下心来考虑,他的优点也还是很多的,例如:

  • 不同项目之间,如果需要复用相同的组件或者方法,现在就可以很方便的引用了,同时,这些公用方法一旦修改了,其他项目的相应逻辑交互也都更新了,不同在担心忘了安装或者更新,同时也比单纯的 复制黏贴 要更科学

这里插一句,很多公司的项目说是独立的,其实都是从已有的项目中各种复制来的,连带着以前的 bug 也都有了,还不如放一起呢

  • 也不是所有的项目都适合放在一起,只有项目之间重合度高的,才应该放一起,例如:管理系统,基本表单操作之类的复用度很高,如果是不相关的项目,彼此没有交集,那就别折腾了
  • 不同项目之间,如果拆分的力度比较细,互相之间有调用,那就适合放在一起,最常见的是 npm 库,不同的库之间可能有依赖,同时每个库还需要单独发布
  • 它倡导了一种开放,透明,共享的组织文化,所有的开发者都可以浏览学习其他人的代码

说完了 Monorepo ,离真正应用还是有点差距,多个项目之间需要保证自己的独立性,还需要能方便的根据其他项目的变动做出相应的改变,目前市面上也有很多其他的方便管理 Monorepo 的工具,例如:lernajs,幸运的是,pnpm 也对 Monorepo 有着良好的支持,pnpm 称他为 workspace

值得一提的是,vite 也对 Monorepo 做了支持,这使得当引用的其他库发生变化时,正在使用 vite dev 开发的项目也会热更新,详细可见Monorepo 和链接依赖

Workspace

pnpm 可以创建一个 workspace 将多个项目合并到一个中,一个 workspace 的根目录下必须有 pnpm-workspace.yaml 文件,常见的 pnpm-workspace.yaml 类似于下面这种配置,可以定义哪些文件或者文件夹应该包含于 workspace 中

packages:
  # all packages in subdirs of packages/ and components/
  - 'packages/**'
  - 'components/**'
  # exclude packages that are inside test directories
  - '!**/test/**'

在 workspace 根目录使用 pnpm install 命令时,会自动将 workspace 中的所有项目执行 pnpm install

workspace: 协议

pnpm 支持协议 workspace:,当使用这个协议时,pnpm 只会解析本地 workspace 中的包,workspace: 协议的使用方法和 package.json 引用包的方法一致

"foo": "workspace:*"
"foo": "workspace:../foo"
"foo": "workspace:~",
"foo": "workspace:^",
"zoo": "workspace:^1.5.0"

当需要发布包时,例如使用 pnpm pack 或者 pnpm publish 命令时,将动态的把 workspace: 协议替换为真正的版本号

结语

pnpm 目前被越来越多的人使用,其中也包括 vue 这样的一线开源框架,具体可以参见 使用示例

在诸如 pnpm 或者 yarn 这样的开源项目影响下,npm 也在反思自己,也及时的做出了更新,例如:支持 workspace 等功能,希望这样的良性循环也让 js 社区越来越好,或许有一天我还会重投 npm 的怀抱也说不定

以上就是使用pnpm包管理器替代npm及yarn的命令示例的详细内容,更多关于pnpm包管理器替代npm及yarn命令的资料请关注我们其它相关文章!

(0)

相关推荐

  • yarn与npm的命令行小结

    一.首先需要了解的命令 npm install === yarn -- install 安装是默认行为. npm install taco --save === yarn add taco -- taco 包立即被保存到 package.json 中. npm uninstall taco --save === yarn remove taco 在 npm 中,可以使用 npm config set save true 设置 - -save 为默认行为,但这对多数开发者而言并非显而易见的.在 y

  • JS新包管理工具yarn和npm的对比与使用入门

    这篇文章会通过以下几个方面介绍yarn的: yarn对比npm解决了什么问题,带来哪些便利. 获取yarn的正确姿势 yarn的使用入门(介绍一些常用的命令 个人使用心得 yarn对比npm的优点 根据官方文档yarn具有6大优点 1.离线模式 yarn会有一个缓存目录,会缓存以前安装过的软件包,再次安装时就不必从网络下载了,大大加速安装速度. 这一点很重要,npm 饱受诟病的一点就是,每次安装依赖,都需要从网络下载一大堆东西,而且是全部重新下载,工程多的时候比较烦人. 我司部署node项目,是

  • 一文带你了解前端包管理工具npm、yarn和pnpm

    目录 为什么需要包管理工具? 版本管理规范 前端主流包管理工具 yarn vs npm vs pnpm 包管理工具安装和版本切换 安装项目依赖 npm .yarn 和 pnpm 常用命令 安全性 lock 文件 性能对比 pnpm 的优势 总结 为什么需要包管理工具? 每种主流编程语言都有包管理工具,比如 java 的 Maven.Gradle,Python 的 pip,nodejs 的 npm.yarn.pnpm 等. 包管理工具的主要作用是管理第三方依赖,也可以看成一个"轮子"工厂

  • pnpm的安装和使用指南(推荐!)

    目录 什么是pnpm pnpm优势 与 npm 的差别 pnpm使用 全局安装 设置源 使用 移除 更新 设置存储路径 个人使用 在系统上禁止使用脚本解决方法 总结 什么是pnpm pnpm是 Node.js 的替代包管理器.它是 npm 的直接替代品,但速度更快.效率更高. 为什么效率更高?当您安装软件包时,我们会将其保存在您机器上的全局存储中,然后我们会从中创建一个硬链接,而不是进行复制.对于模块的每个版本,磁盘上只保留一个副本.例如,当使用 npm 或 yarn 时,如果您有 100 个使

  • 使用pnpm包管理器替代npm及yarn的命令示例

    目录 前言 为什么会有 pnpm 不止于此 什么是扁平化的 node_modules pnpm 的 node_modules 如何使用 pnpm 安装 直接安装 通过 npm 安装 通过 HomeBrew 安装( 一种 MacOS 包管理器) 升级 使用 配置 命令 和其他包管理器比较 Monorepo 及 工作空间(Workspace) 什么是 Monorepo Workspace workspace: 协议 结语 前言 今天给大家介绍一种新的包管理器:pnpm,pnpm 由 zkochan

  • Node.js安装教程和NPM包管理器使用详解

    2009年的JSCOnf大会上,一个叫Ryan Dahl的年轻程序员向人们展示了一个他正在做的项目,一个基于Google V8引擎的JavaScript运行平台,它提供了一套事件循环和低IO的应用程序编程接口(API).和其他的服务端平台不同, JavaScript天生就是事件驱动IO,而这个项目又大大降低了编写事件驱动应用程序的复杂度,因此它很快就以不可思议的速度的成长流行起来,并应用到实际项目中.(Jack:这段翻译的不太靠谱,原文:This project was not like oth

  • Node.js包管理器npm的具体使用

    目录 目的 npm init 与 package.json文件 模块安装与管理 安装模块 查看已安装模块 更新模块 删除模块 npx 模块编译 版本控制 换源 使用 nrm 工具换源 使用 cnpm 代替 npm 总结 目的 目前的Node.js安装包中都带有一个重要的工具 包管理器npm .npm主要有两方面功能:下载管理第三方模块:构建与运行项目.npm使用本身并不复杂,但是在大陆的网络环境下使用并不省心,徒增许多工作量.这篇文章将对相关内容做个说明. npm init 与 package.

  • Node.js基础入门之模块与npm包管理器使用详解

    目录 require函数 模块分类 第三方模块 1. 安装第三方模块 2. 引入第三方模块 3. 示例测试 系统模块 require注意事项 exports导出对象 1. exports示例 2. exports注意事项 module模块对象 package.json包描述文件 1. 什么是package.json ? 2. 如何创建package.json文件? NPM基础 1. 常用npm命令 2. npm 示例 cnpm基础 1. 什么是cnpm ? 2. 使用cnpm 控制台输出 1.

  • Node.js包管理器Yarn的入门介绍与安装

    前言 这两天大家有没有都被Yarn悄悄刷了屏,最近Facebook 发布了新的 node.js 包管理器 Yarn 用以替代 npm .为了跟上 Javascript 这股潮 流的脚步,大概的浅尝了一下这个自称是又快又可信赖又安全的包管理,所以写的内容不会很详细,更多的可能只是针对这个全新的包管理与 npm 的不同之处来对比.也可能有些地方写得不对,如果有的话,欢迎指正. 一.安装 首先当然是安装啦.跟 npm 这种被钦点而随 nodejs 一起被安装的包管理器不同, Yarn 需要自行手动安装

  • 在linux中使用包管理器安装node.js

    网上文章中,在linux下安装node.js都是使用源码编译,其实node的github上已经提供了各个系统下使用各自的包管理器(package manager)安装node.js的方法. 1. 在Ubuntu中,使用如下命令: 复制代码 代码如下: curl -sL https://deb.nodesource.com/setup | sudo bash - sudo apt-get install -y nodejs 如果需要使用npm安装本地组件,还需要执行如下命令: 复制代码 代码如下:

  • AERGO SHIP:用于开发智能合约的包管理器

    AERGO SHIP:用于开发智能合约的包管理器 用于构建.测试和部署分布式应用程序的客户端框架和开发环境 构建大型分布式应用程序是很困难的,因为对其进行测试,使其实现端到端工作,并进行部署是一个非常耗时的过程.通过AERGO,我们计划让一切变得与众不同. AERGO是一个为在实现基于区块链的系统和应用程序时面临众多独特挑战的企业提供解决方案的平台.为了提高开发.测试和部署智能合约的效率和易用性,我们创建了SHIP.SHIP是Lua智能合约包管理器.它将本地开发环境与Git和分布式分类账连接起来

  • Flutter 包管理器和资源管理使用学习

    目录 什么叫包管理器 Flutter 包管理器 Pub仓库 资源管理 配置图片资源 配置全局字体资源 结束语 什么叫包管理器 包管理器就是用来管理程序运行依赖的一个配置应用.在程序运行中,我们会用到各种各样的第三方程序包,若我们手动管理这些程序,他将变得十分臃肿.这时候便诞生了包管理器,类似于手机中的AppStore.比如说我们手机中的某个程序更新了,我们就可以通过AppStore来更新.同样的我们可以通过包管理来更新我们程序中用到的依赖包. Flutter 包管理器 Flutter包管理器是Y

  • python小白学习包管理器pip安装

    pip对于使用python的朋友并不陌生,当你想安装python模块的时候一定会首先想到它.pip 是一个安装和管理 Python 包的工具 , 是 easy_install 的一个替换品. 今天来说一下,pip的安装方法. 方法一:脚本安装 $ wget https://bootstrap.pypa.io/get-pip.py $ [sudo] python get-pip.py 方法二:源码安装: $ curl -O https://pypi.python.org/packages/sour

  • 国产化之银河麒麟安装.NetCore包管理器方式(步骤详解)

    目录 背景 环境 安装步骤 1.更新软件列表 2.添加Microsoft包签名密钥到受信任包签名密钥列表 3.安装.netcore 3.1sdk 4.检查安装结果 测试 背景 某个项目需要实现基础软件全部国产化,其中操作系统指定银河麒麟,数据库使用达梦V8,CPU平台的范围包括x64.龙芯.飞腾.鲲鹏等. 考虑到这些基础产品对.NETCore的支持,最终选择了3.1版本.主要原因就是龙芯搞了自研CPU架构,用户量不够大,.NET官方并没有专门针对龙芯的支持,而龙芯团队只对.netcore3.1做

随机推荐