pnpm、npm、yarn 包管理工具『优劣对比』及『环境迁移』

前言

博主在开发前端网站的时候,发现随着开发的项目的逐渐增多,安装的依赖包越来越臃肿,依赖包的安装速度也是非常越来越慢,多项目开发管理也是比较麻烦。之前我就了解过 pnpm,但是当时担心更换包管理环境可能会出现的依赖等问题,并且也没有急切的需求,所以当时并没有立即更换

综上所述,随着上面问题的出现,更换包管理环境也逐渐提上日程,所以本文主要将会简单对比 pnpm 和 npm / yarn ,并且详细讲解如何在多项目环境中迁移到 pnpm

Pnpm安装与使用教程- 小白龙博客

介绍

npm v2

此时期主要是采用简单的递归依赖方法,最后形成高度嵌套的依赖树。然后就会造成如下问题:重复依赖嵌套地狱,空间资源浪费,安装速度过慢,文件路径过长等问题。大家都很熟悉,这里不再详细解释

npm v3

v3 版本作了较大的更新,开始采取扁平化的依赖结构。这样的依赖结构可以很好的解决重复依赖的嵌套地狱问题,但是却出现扁平化依赖算法耗时长这样新的问题

官方仓库 issue 的解释:npm@3 wants to be faster · Issue #8826 · npm/npm (github.com)

npm v5

为了解决上面出现的扁平化依赖算法耗时长问题,npm 引入 package-lock.json 机制,package-lock.json 的作用是锁定项目的依赖结构,保证依赖的稳定性,有兴趣的朋友可以直接查看官方文档

官方文档:package.json | npm Docs (npmjs.com)

注:其实在 package-lock.json 机制出现之前,可以通过 npm-shrinkwrap 实现锁定依赖结构,但是 npm-shrinkwrap 默认关闭,需要主动执行。

yarn

官网:Home page | Yarn (yarnpkg.com)

首先需要提出的是 yarn 出现时间为 2016 年,此时 npm 处于 v3 时期,其实当时 yarn 解决的问题基本就是 npm v5 解决的问题,包括使用 yarn.lock 等机制,锁定版本依赖,实现并发网络请求,最大化网络资源利用率,其次还有利用缓存机制,实现了离线模式

其实后面很多 npm 都是在学习 yarn 的机制,上面的机制目前 npm 基本也都实现了,就目前而言 npm 和 yarn 其实并没有差异很大,具体使用 npm 还是 yarn 可以看个人需求

pnpm

中文官网:pnpm - 速度快、节省磁盘空间的软件包管理器 | pnpm中文文档 | pnpm中文网

pnpm 内部使用基于内容寻址的文件系统来存储磁盘上所有的文件,这样可以做到不会出现重复安装,在项目中需要使用到依赖的时候,pnpm 只会安装一次,之后再次使用都会直接硬链接指向该依赖,极大节省磁盘空间,并且加快安装速度

注:硬链接是多个文件名指向同一个文件的实际内容,而软链接(符号链接)是一个独立的文件,指向另一个文件或目录的路径

也许有人说 yarn 默认也是扁平化安装方式,但是 yarn 有独特的 PnP 安装方式,可以直接去掉 node_modules,将依赖包内容写在磁盘,节省了 node 文件 I/O 的开销,这样也能提升安装速度,但是 yarn PnP 和 pnpm 机制是不同的,且总体来说安装速度 pnpm 是要快于 yarn PnP 的,详情请看下面官方文档

官方文档:Overview | Yarn (yarnpkg.com)

最后就是 pnpm 是默认支持 monorepo 多项目管理的,在日渐复杂的前端多项目开发中尤其适用,也就说我们不再需要 lerna 来管理多包项目,可以使用 pnpm + Turborepo 作为我们的项目管理环境

配置工作空间官方文档:工作空间(Workspace) | pnpm

img

还有就是 pnpm 还能管理 nodejs 版本,可以直接替代 nvm,命令如下所示

# 安装 LTS 版本
pnpm env use --global lts
# 安装指定版本
pnpm env use --global 16

迁移

迁移过程中主要有如下问题:因为使用 npm 或 yarn 安装依赖项时,所有包都被提升到模块目录的根目录。因此,源代码可以访问未作为依赖项添加到项目的依赖项。但是默认情况下,pnpm 使用链接仅将项目的直接依赖项添加到模块目录的根目录中

这意味着如果 package.json 没有引用的依赖,那么它将无法解析。这是迁移中的最大障碍。可以使用 auto-install-peers 设置自动执行此操作(默认情况下是false)

对于多个使用 npm 安装依赖的项目,单独删除依赖包很耗时间,我们可以使用 npkill ,该工具可以列出系统中的任何 node_modules 目录以及它们占用的空间。然后可以选择要删除的依赖以释放空间

npkill-demo-0.10.0

首先全局安装包

npm i -g pnpm

迁移步骤如下

1.首先使用 npkill 删除 node_modules 依赖包

2.项目根目录创建 .npmrc,填写如下内容

auto-install-peers=true

3.导入依赖锁定文件(pnpm-lock.yaml)

保证根目录有如下依赖锁定文件(npm-shrinkwrap.json,package-lock.json,yarn.lock)

然后执行如下命令

pnpm import pnpm-lock.yaml

4,最后执行 pnpm i 安装依赖

问题

生成依赖文件警告

官方 issue 解释: Unmet peer dependencies and The command – pnpm/pnpm (github.com)

生成 pnpm-lock.yaml 文件时出现如下警告

 WARN  Issues with peer dependencies found
.
└─┬ vuepress 1.9.9└─┬ @vuepress/core 1.9.9└─┬ vue-loader 15.10.1└─┬ @vue/component-compiler-utils 3.3.0└─┬ consolidate 0.15.1├── ✕ unmet peer react-dom@^16.13.1: found 15.7.0└── ✕ unmet peer react@^16.13.1: found 15.7.0

这是因为在 npm 3 中,不会再强制安装 peerDependencies (对等依赖)中所指定的包,而是通过警告的方式来提示我们。pnpm 会在全局缓存已经下载过的依赖包,如果全局缓存的依赖版本与项目 package.json 中指定的版本不一致,就会出现这种 hint 警告

我们可以在项目的 package.json 中配置 peerDependencyRules 忽略对应的警告提示

{"pnpm": {"peerDependencyRules": {"ignoreMissing": ["react"]}}
}

或者说直接在 .npmrc 配置文件中直接关闭严格的对等依赖模式,可以添加 strict-peer-dependencies=false 到配置文件中,或者执行如下命令

npm config set strict-peer-dependencies=false

然后也可能会出现警告 deprecated subdependencies found,暂时可以忽略

幽灵依赖问题

在最后安装依赖的时候可能会出现幽灵依赖问题,幽灵依赖就是没有在package.json中,但是项目中,或者引用的包中使用到的依赖

举个例子,比如我们现在使用 npm 安装了 v-viewer 依赖,同时 viewerjsv-viewer 的依赖项,由于扁平化依赖机制,我们可以在 node_modules/v-viewer/package.json 中看到声明的 viewerjs 依赖,即使项目根目录下的 package.json 没有声明 viewerjs 依赖,我们仍旧可以使用,这就是幽灵依赖

而现在我们切换为 pnpm 后,在默认情况下不允许访问未声明的依赖,有以下两种解决方案

1.自行安装未声明依赖项

幽灵依赖自动扫描工具:@sugarat/ghost - npm (npmjs.com)

pnpm i -S viewerjs

或者说某些版本 pnpm 会自动爆出幽灵依赖错误 missing peer ...,也可以直接不使用上面的扫描工具,直接自行安装后面的 ... 依赖

2.找到.npmrc 文件,在其中配置 public-hoist-pattern 或者 shamefully-hoist 字段,将依赖提升到根node_modules 目录下解决,也就是所谓的依赖提升

依赖提升官方文档:.npmrc | pnpm

# .npmrc
# 提升含有 eslint(模糊匹配)、prettier(模糊匹配)、viewerjs(精确匹配) 的依赖包到根 node_modules 目录下
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
public-hoist-pattern[]=viewerjs# 提升所有依赖到根 node_modules 目录下,相当于 public-hoist-pattern[]=*,与上面一种方式一般二选一使用
shamefully-hoist=true

当然,极不推荐用这样的方式解决依赖问题,这样没有充分利用 pnpm 依赖访问安全性的优势,又走回了 npm / yarn 的老路。

参考链接

  • pnpm 对比 npm/yarn 好在哪里 - 掘金 (juejin.cn)
  • 现在我更推荐 pnpm 而不是 npm/yarn? - 掘金 (juejin.cn)
  • 如何将 npm / yarn 项目迁移到 pnpm? - 掘金 (juejin.cn)
  • 浅谈 npm, yarn, pnpm之间的区别 - 掘金 (juejin.cn)
  • vue 配套生态已经全面使用 pnpm 了 - 掘金 (juejin.cn)
  • 打造高效Monorepo:Turborepo、pnpm、Changesets实践 – UU跑腿技术团队 (uupt.com)
  • 新一代包管理工具 pnpm 使用心得 - 知乎 (zhihu.com)
  • ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies | 天問-专注于大前端技术 (tiven.cn)

本文由博客一文多发平台 OpenWrite 发布!

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

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

相关文章

十、2023.10.4.计算机网络(one).10

文章目录 1、简述静态路由和动态路由?2、说说有哪些路由协议,都是如何更新的?3、简述域名解析过程,本机如何干预域名解析?4、简述 DNS 查询服务器的基本流程是什么?DNS 劫持是什么?5、简述网关的…

FFmpeg 基础模块:容器相关的 API 操作

目录 AVFormat 模块 AVFormat 前处理部分 AVFormat 读写处理部分 小结 思考 FFmpeg 目录中包含了 FFmpeg 库代码目录、构建工程目录、自测子系统目录等,具体内容如下: 现在你知道 FFmpeg 的源代码目录中都包含了哪些内容,在之后使用 FFm…

FFmpeg日志系统、文件与目录、操作目录

目录 FFmpeg日志系统 FFmpeg文件与目录操作 FFmpeg文件的删除与重命名 FFmpeg操作目录及list的实现 操作目录重要函数 操作目录重要结构体 FFmpeg日志系统 下面看一个简单的 demo。 #include <stdio.h> #include <libavutil/log.h>int main(int argc,char* …

多头注意力机制

1、什么是多头注意力机制 从多头注意力的结构图中&#xff0c;貌似这个所谓的多个头就是指多组线性变换&#xff0c;但是并不是&#xff0c;只使用了一组线性变换层&#xff0c;即三个变换张量对 Q、K、V 分别进行线性变换&#xff0c;这些变化不会改变原有张量的尺寸&#xf…

【Vue面试题十一】、Vue组件之间的通信方式都有哪些?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;Vue组件之间的通信方式都…

浅谈CDN内容分发与全局负载均衡

CDN简介 CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络&#xff0c;依靠部署在各地的边缘服务器&#xff0c;通过中心平台的负载均衡、内容分发、调度等功能模块&#xff0c;使用户就近获取所需内容&#xff0c…

C语言学生成绩录入系统

一、系统概述 该系统是一个由链表创建主菜单的框架&#xff0c;旨在快速创建学生成绩录入系统的主菜单结构。其主要任务包括&#xff1a; 实现链表的创建、插入和遍历功能&#xff0c;用于存储和展示学生成绩录入系统各个模块的菜单项。 2. 提供用户友好的主菜单界面&#xf…

【回顾一下Docker的基本用法】

文章目录 回顾一下Docker的基本用法1.初识Docker1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结 1.2.Docker和虚拟机的区别1.3.Docker架构1.3.1.镜像和容器1.3.2.DockerHub1.3.3.Docker架构1.3.4.小结 1.4.…

CSS小计

1&#xff1a;设置图片随窗缩放 使用百分比 width: 100%;height: 100%; 使用vmin: 将可视区域分为100vmin width: 100vmin;height: 100vmin; 2:设置字体颜色与背景色融合 mix-blend-mode: difference 3: 设置宽度自适应 width:fit-content 4:外边距合并 当两个相领的两个容…

Git 学习笔记 | 使用码云

Git 学习笔记 | 使用码云 Git 学习笔记 | 使用码云注册登录码云&#xff0c;完善个人信息设置本机绑定SSH公钥&#xff0c;实现免密码登录创建远程仓库 Git 学习笔记 | 使用码云 注册登录码云&#xff0c;完善个人信息 网址&#xff1a;https://gitee.com/ 可以使用微信&…

RT-Thread 内存管理(学习二)

内存堆管理应用示例 这是一个内存堆的应用示例&#xff0c;这个程序会创建一个动态的线程&#xff0c;这个线程会动态申请内存并释放&#xff0c;每次申请更大的内存&#xff0c;当申请不到的时候就结束。 #include <rtthread.h>#define THREAD_PRIORITY 25 #defi…

机器学习之旅-从Python 开始

你想知道如何开始机器学习吗&#xff1f;在这篇文章中&#xff0c;我将简要概括一下使用 Python 来开始机器学习的一些步骤。Python 是一门流行的开源程序设计语言&#xff0c;也是在人工智能及其它相关科学领域中最常用的语言之一。机器学习简称 ML&#xff0c;是人工智能的一…

lv7 嵌入式开发-网络编程开发 08 TCP并发功能

目录 1 TCP 多进程并发 1.1 现象&#xff1a; 1.2 多进程并发 2 僵尸进程处理 3 TCP并发多线程 4 练习 1 TCP 多进程并发 1.1 现象&#xff1a; 之前的代码&#xff0c;先关服务端&#xff0c;再次打开会出现错误bind:Address already in use 使用setsockopt 地址快速重…

vuejs中使用axios时如何追加数据

前言 在vuejs中使用axios时&#xff0c;有时候需要追加数据,比如,移动端下拉触底加载,分页加载,滑动滚动条,等等,这时候就需要追加数据了,下面我们来演示下. 代码演示 <template><div><div><el-button type"primary" click"handleBtnGetJ…

【智能家居项目】裸机版本——设备子系统(LED Display 风扇)

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 输入子系统中目前仅实现了按键输入&#xff0c;剩下的网络输入和标准输入在以后会逐步实现&am…

三十二、【进阶】hash索引结构

1、hash索引结构 &#xff08;1&#xff09;简述&#xff1a; hash索引&#xff0c;就是采用一定的hash算法&#xff0c;将键值换算成新的hash值&#xff0c;映射到对应的槽位上&#xff0c;然后存储在hash表中。 &#xff08;2&#xff09;图示&#xff1a; 2、hash索引结构…

阿里云服务器ECS详细介绍_云主机_服务器托管_弹性计算

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网分享阿…

手写Demo体验volatile可见性的作用

volatile是java的关键字&#xff0c;作用&#xff1a;①保证线程间的可见性&#xff1b;②防止指令重排。下面看一个demo&#xff0c;启动2个线程&#xff0c;一个线程读取flag变量的值&#xff0c;另外一个线程修改flag变量的值。 public class VolatileDemo {private static…

二、Excel VBA 简单使用

Excel VBA 从入门到出门一、Excel VBA 是个啥&#xff1f;二、Excel VBA 简单使用 &#x1f44b;Excel VBA 简单使用 ⚽️1. 如何在Excel中手动编写VBA代码⚽️2. 如何在 Excel 中运行 VBA 代码⚽️3. 如何在Excel中记录VBA代码⚽️4. 如何在Excel中编辑录制的VBA代码⚽️5. 如…

集合的基本运算

集合的运算等式&#xff1a; 常用的集合运算不等式&#xff1a; 、 试题 A&#xff0c;B&#xff0c;C是集合&#xff0c;证明&#xff1a;(A-B)-CA-(B∪C) 【答案】 设A、B、C是集合&#xff0c;证明 (A∪B)-C(A-C)∪(B-C)。 【答案】 已知A{1,2,3}&#xff0c;A-B{1,2}&…