npm 的局限性

  1. 磁盘空间浪费

在 npm
早期版本中,每个项目的node_modules目录都会完整复制所有依赖包,即使多个项目依赖同一个包的相同版本,也会重复存储。这导致磁盘空间被大量占用,随着项目数量的增加,存储成本显著上升。虽然
npm v3
引入了扁平化结构,一定程度上减少了重复,但仍无法彻底解决问题。例如,在一个拥有多个项目的开发环境中,如果每个项目都依赖
lodash,那么每个项目的node_modules目录中都会有一份 lodash 的副本。

  1. 安装速度较慢

npm
安装依赖时,需要从远程仓库下载每个包并写入node_modules目录,对于大型项目,尤其是依赖众多的项目,这个过程涉及大量的
I/O 操作和网络请求,安装速度会受到明显影响。即使在 npm v5
之后支持了并行下载,在面对复杂的依赖树时,安装时间仍然较长。例如,当安装一个包含上百个依赖包的项目时,npm
可能需要数分钟甚至更长时间才能完成安装。 幽灵依赖问题 npm 的扁平化node_modules结构带来了 “幽灵依赖”
问题。项目可以访问未在package.json中声明的依赖包,这是因为依赖包的嵌套依赖可能被提升到node_modules的根目录,从而导致项目代码中能够直接引用这些未声明的依赖。这种不明确的依赖关系使得项目的依赖管理变得混乱,一旦依赖包的版本发生变化,可能会导致项目在运行时出现难以排查的错误。例如,项目
A 依赖包 B,而包 B 又依赖包 C,由于扁平化结构,包 C 可能会被提升到node_modules根目录,项目 A
的代码中就可以直接引用包 C,即使项目 A 的package.json中并没有声明对包 C 的依赖。

  1. pnpm 的优势

高效的磁盘空间管理 pnpm 使用内容寻址存储和符号链接 /
硬链接技术来管理依赖。所有依赖项都存储在全局共享存储中,当项目安装依赖时,pnpm
会通过硬链接将依赖包从全局存储链接到项目的node_modules目录,而不是复制整个包。这意味着,无论有多少个项目依赖同一个包的相同版本,磁盘上只会存储一份该包的文件。例如,假设有
100 个项目都依赖 lodash,在 pnpm 的管理下,lodash
在磁盘上只占用一份空间,大大节省了磁盘资源。而且,当依赖包的版本更新时,pnpm
只会将有差异的文件添加到存储中,进一步减少了磁盘空间的占用。 快速的安装速度 pnpm
的安装过程分为三个阶段:依赖解析、目录结构计算和链接依赖项。在依赖解析阶段,识别并获取仓库中没有的依赖;目录结构计算阶段,根据依赖关系计算node_modules目录结构;链接依赖项阶段,将以前安装过的依赖项从存储区直接链接到node_modules。这种方式避免了重复下载和复制文件,尤其是在处理大量依赖项时,安装速度明显快于
npm。在有缓存的情况下,或者安装已经存在于全局仓库中的包时,pnpm 的安装速度几乎可以达到 “秒级”,极大地提高了开发效率。
清晰的依赖结构,杜绝幽灵依赖 pnpm 创建的是一个嵌套的、有严格依赖关系的node_modules结构。在 pnpm
的node_modules中,只会包含在package.json中明确声明的依赖。项目依赖的包所依赖的其他包,会被存放在node_modules/.pnpm/这个特殊目录里,并通过符号链接的方式链接到相应包的node_modules中。这就从根本上杜绝了
“幽灵依赖”
问题,确保项目的依赖关系清晰、可靠,不会出现意外引用未声明依赖的情况。在项目代码中尝试引用未在package.json中声明的依赖时,pnpm
会直接报错,保证了项目依赖的纯净性。 对 Monorepo 的良好支持 在处理 Monorepo(多包仓库)时,npm 的支持相对较弱,而
pnpm 原生支持
Monorepo,并且配置相对简单。通过在项目根目录创建pnpm-workspace.yaml文件并声明对应的工作区,就可以方便地管理多个包和项目。在一个包含多个前端项目和后端项目的
Monorepo 中,使用 pnpm 可以轻松实现依赖的共享和管理,减少重复安装,提高整个项目组的开发效率。

  1. 案例对比

磁盘空间占用对比 以一个实际的开发场景为例,有 5 个 React 项目,使用 npm 管理依赖时,这 5
个项目的node_modules目录总共占用了 8.7G 的磁盘空间;而使用 pnpm 后,同样的 5
个项目,node_modules相关的存储总共只占用了 3.2G,直接节省了 5G
左右的磁盘空间。对于磁盘空间有限的开发者来说,这无疑是一个非常有吸引力的优势。 安装速度对比 在安装一个具有复杂依赖树的项目时,使用 npm
执行npm install命令,等待时间长达数分钟;而使用 pnpm 执行pnpm
install,安装时间缩短了一半以上,极大地减少了开发过程中的等待时间,提高了开发节奏。 依赖管理稳定性对比 在一个团队协作项目中,由于
npm 的package-lock.json文件有时不能很好地锁定依赖版本,导致不同开发者安装的依赖版本不一致,经常出现
“在我电脑上能运行,在别人电脑上报错” 的情况。而切换到 pnpm
后,其pnpm-lock.yaml文件更严格地记录了依赖的版本、来源和包的哈希值,保证了不同开发者安装的依赖结构几乎 100%
一致,项目交接和协同开发变得更加顺畅,减少了因依赖不一致导致的问题。 综上所述,pnpm 在磁盘空间管理、安装速度、依赖结构的清晰性以及对
Monorepo 的支持等方面,都展现出了明显优于 npm 的特性。在当今前端项目日益复杂、依赖管理愈发重要的背景下,pnpm
为开发者提供了更高效、更可靠的包管理解决方案。

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

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

相关文章

Transformer实战(18)——微调Transformer语言模型进行回归分析

Transformer实战(18)——微调Transformer语言模型进行回归分析0. 前言1. 回归模型2. 数据处理3. 模型构建与训练4. 模型推理小结系列链接0. 前言 在自然语言处理领域中,预训练 Transformer 模型不仅能胜任离散类别预测,也可用于连…

【Linux】【实战向】Linux 进程替换避坑指南:从理解 bash 阻塞等待,到亲手实现能执行 ls/cd 的 Shell

前言:欢迎各位光临本博客,这里小编带你直接手撕,文章并不复杂,愿诸君耐其心性,忘却杂尘,道有所长!!!! IF’Maxue:个人主页🔥 个人专栏…

linux常用命令 (3)——系统包管理

博客主页:christine-rr-CSDN博客 ​​​​​ ​​ hi,大家好,我是christine-rr ! 今天来分享一下linux常用命令——系统包管理 目录linux常用命令---系统包管理(一)Debian 系发行版(Ubuntu、Debian、Linux …

YOLOv8 mac-intel芯片 部署指南

🚀 在 Jupyter Notebook 和 PyCharm 中使用 Conda 虚拟环境(YOLOv8 部署指南,Python 3.9) YOLOv8 是 Ultralytics 开源的最新目标检测模型,轻量高效,支持分类、检测、分割等多种任务。 在 Mac(…

【高等数学】第十一章 曲线积分与曲面积分——第六节 高斯公式 通量与散度

上一节:【高等数学】第十一章 曲线积分与曲面积分——第五节 对坐标的曲面积分 总目录:【高等数学】 目录 文章目录1. 高斯公式2. 沿任意闭曲面的曲面积分为零的条件3. 通量与散度1. 高斯公式 设空间区域ΩΩΩ是由分片光滑的闭曲面ΣΣΣ所围成&#x…

IDEA试用过期,无法登录,重置方法

IDEA过期,重置方法: IntelliJ IDEA 2024.2.0.2 (亲测有效) 最新Idea重置办法!: 方法一: 1、删除C:\Users\{用户名}\AppData\Local\JetBrains\IntelliJIdea2024.2 下所有文件(注意:是子目录全部删除) 2、删除C:\Users\{用户名}\App…

创建用户自定义桥接网络并连接容器

1.创建用户自定义的 alpine-net 网络[roothost1 ~]# docker network create --driver bridge alpine-net 9f6d634e6bd7327163a9d83023e435da6d61bc6cf04c9d96001d1b64eefe4a712.列出 Docker 主机上的网络[roothost1 ~]# docker network ls NETWORK ID NAME DRIVER …

Vue3 + Vite + Element Plus web转为 Electron 应用,解决无法登录、隐藏自定义导航栏

如何在vue3 Vite Element Plus搭好的架构下转为 electron应用呢? https://www.electronjs.org/zh/docs/latest/官方文档 https://www.electronjs.org/zh/docs/latest/ 第一步:安装 electron相关依赖 npm install electron electron-builder concurr…

qt QAreaLegendMarker详解

1. 概述QAreaLegendMarker 是 Qt Charts 模块中的一部分,用于在图例(Legend)中表示 QAreaSeries 的标记。它负责显示区域图的图例项,通常包含区域颜色样例和对应的描述文字。图例标记和对应的区域图关联,显示区域的名称…

linux 函数 kstrtoul

kstrtoul 函数概述 kstrtoul 是 Linux 内核中的一个函数&#xff0c;用于将字符串转换为无符号长整型&#xff08;unsigned long&#xff09;。该函数定义在 <linux/kernel.h> 头文件中&#xff0c;常用于内核模块中解析用户空间传递的字符串参数。 函数原型 int kstrtou…

LLM(三)

一、人类反馈的强化学习&#xff08;RLHF&#xff09;微调的目标是通过指令&#xff0c;包括路径方法&#xff0c;进一步训练你的模型&#xff0c;使他们更好地理解人类的提示&#xff0c;并生成更像人类的回应。RLHF&#xff1a;使用人类反馈微调型语言模型&#xff0c;使用强…

DPO vs PPO,偏好优化的两条技术路径

1. 背景在大模型对齐&#xff08;alignment&#xff09;里&#xff0c;常见的两类方法是&#xff1a;PPO&#xff1a;强化学习经典算法&#xff0c;OpenAI 在 RLHF 里用它来“用奖励模型更新策略”。DPO&#xff1a;2023 年提出的新方法&#xff08;参考论文《Direct Preferenc…

BLE6.0信道探测,如何重构物联网设备的距离感知逻辑?

在物联网&#xff08;IoT&#xff09;无线通信技术快速渗透的当下&#xff0c;实现人与物、物与物之间对物理距离的感知响应能力已成为提升设备智能高度与人们交互体验的关键所在。当智能冰箱感知用户靠近而主动亮屏显示内部果蔬时、当门禁系统感知到授权人士靠近而主动开门时、…

【计算机 UTF-8 转换为本地编码的含义】

UTF-8 转换为本地编码的含义 详细解释一下"UTF-8转换为本地编码"的含义以及为什么在处理中文时这很重要。 基本概念 UTF-8 编码 国际标准&#xff1a;UTF-8 是一种能够表示世界上几乎所有字符的 Unicode 编码方式跨平台兼容&#xff1a;无论在哪里&#xff0c;UTF-8 …

4.6 变体

1.变体简介 2.为什么需要变体 3.变体是如何产生的 4.变体带来的麻烦 5.multi_compile和shader_feature1.变体简介 比如我们开了一家餐厅, 你有一本万能的菜单(Shader源代码), 上面包含了所有可能的菜式; 但是顾客每次来点餐时, 不可能将整本菜单都做一遍, 他们会根据今天有没有…

猿辅导Android开发面试题及参考答案(下)

为什么开发中要使用线程池,而不是直接创建线程(如控制线程数量、复用线程、降低开销)? 开发中优先使用线程池而非直接创建线程,核心原因是线程池能优化线程管理、降低资源消耗、提高系统稳定性,而直接创建线程存在难以解决的缺陷,具体如下: 控制线程数量,避免资源耗尽…

【网络通信】IP 地址深度解析:从技术原理到企业级应用​

IP 地址深度解析&#xff1a;从技术原理到企业级应用​ 文章目录IP 地址深度解析&#xff1a;从技术原理到企业级应用​前言一、基础认知&#xff1a;IP 地址的技术定位与核心特性​1.1 定义与网络层角色1.2 核心属性与表示法深化二、地址分类&#xff1a;从类别划分到无类别路…

grafana实践

一、如何找到grafana的插件目录 whereis grafana grafana: /etc/grafana /usr/share/grafana插件安装目录、默认安装目录&#xff1a; 把vertamedia-clickhouse-datasource-3.4.4.zip解压到下面目录&#xff0c;然后重启就可以了 /var/lib/grafana/plugins# 6. 设置权限 sudo …

uniapp 文件查找失败:main.js

重装HbuilderX vue.config.js 的 配置 有问题main.js 框架能自动识别 到&#xff0c;不用多余的配置

KEIL烧录时提示“SWD/JTAG communication failure”的解决方法

最新在使用JTAG仿真器串口下载调试程序时&#xff0c;老是下载不成功&#xff0c;识别不到芯片&#xff0c;我尝试重启keil5或者重新插拔仿真器连接线、甚至重启电脑也都不行&#xff0c;每次下载程序都提示如下信息&#xff1a;在确定硬件连接没有问题之后&#xff0c;就开始分…