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

简述下npm,cnpm,yarn和pnpm的区别,以及跟在后面的-g,--save, --save-dev代表着什么

文章目录

  • 前言
  • 一、npm,cnpm,yarn和pnpm的基本介绍和特点
      • 1.npm (Node Package Manager)
      • 2. Yarn
      • 3. cnpm (China npm)
      • 4. pnpm
  • 二、简述npm和pnpm 的存储方式和依赖数
      • 1.存储方式
      • 2.依赖树
  • 三、两者依赖树的差异导致结果的对比
  • 四、简单说说-g,--save, --save-dev代表着什么
  • 总结


前言

最近总有些同事问我为什么喜欢使用pnpm,除此之外慢慢开始带实习生,为了让一些基础的能够认清这些差别,所以简述下我的认知(仅供参考)
yarn、npm、cnpm 和 pnpm 是四种流行的 JavaScript 和 Node.js 包管理工具。
虽然它们都用于管理项目依赖,但在设计理念、功能和使用方式上存在一些显著的区别。


一、npm,cnpm,yarn和pnpm的基本介绍和特点

1.npm (Node Package Manager)

  • 基本介绍:
    • npm 是 Node.js 默认的包管理工具,随着 Node.js 的安装自动提供(其实你安装node,就会自带npm下来了)。
  • 特点:
    • 安装方式: 默认情况下,会将依赖包安装到每个项目的 node_modules 目录中。
    • 性能: 安装速度相对较慢,尤其是当项目依赖较多时,因为每次都需要从头开始安装。
    • 依赖管理: 使用扁平化依赖结构,可能导致依赖冲突(如多个版本的同一依赖)。
    • 工作空间支持: 在较新版本中加入了工作空间的支持,但相对功能较为基础。
    • 安装: 随着node版本安装会自带npm命令

2. Yarn

  • 基本介绍:
    • yarn 是 Facebook 开发的包管理工具,旨在提供更快的安装速度和更好的依赖管理。
  • 特点:
    • 安装方式: 默认使用 yarn.lock 文件锁定依赖版本,确保一致性。
    • 性能: 通过并行安装和缓存机制,通常比 npm 更快。
    • CLI 体验: 提供更友好的 CLI 输出和更好的错误提示。
    • 工作空间支持: 支持工作空间,方便管理多包项目。
    • 离线模式: 支持离线安装,依赖已经下载过的包可以在离线状态下使用。
    • 安装: npm i yarn -g

3. cnpm (China npm)

  • 基本介绍:
    • cnpm 是一个专为中国用户设计的 npm 镜像,旨在解决 npm 在中国访问速度慢的问题。
  • 特点:
    • 镜像源: 将 npm 的包使用淘宝的镜像源,从而加速安装。
    • 兼容性: 基本上与 npm 兼容,使用的命令和配置方式类似。
    • 使用场景: 主要用于中国的开发者,以提高访问速度和稳定性。
    • 安装: npm i cnpm -g

4. pnpm

  • 基本介绍:
    • pnpm 是一个高效的包管理器,专注于提高安装效率和减少磁盘空间的使用。
  • 特点:
    • 安装方式: 使用全局存储,所有包只存储一份,通过符号链接(symlink)进行引用,减少磁盘空间的占用。
    • 性能: 通常比 npm 和 yarn 更快,特别是在处理多个项目之间共享依赖时。
    • 依赖管理: 强制确保依赖的一致性,能够更好地处理不同版本的依赖,减少冲突。
    • 工作空间支持: 具有强大的工作空间功能,适合多包项目(monorepos)的管理。
    • 安装: npm i pnpm -g

二、简述npm和pnpm 的存储方式和依赖数

1.存储方式

1. npm 的存储方式
* 依赖安装路径:
	默认情况下,npm 将所有依赖包安装在项目的 node_modules 目录下。每个包的依赖会在其自己的 node_modules 文件夹中。
	如果一个依赖包有自己的依赖(即子依赖),npm 会在该依赖包的目录下再创建一个 node_modules 文件夹来存放这些子依赖。
	
* 扁平化依赖:
	在较新的版本(npm 3及之后),npm 尝试将依赖尽量扁平化。如果多个包依赖于同一版本的依赖,npm 会将其安装在顶层的node_modules 目录中。但如果不同的依赖包需要不同版本的同一依赖,仍然会在相应的依赖包目录中安装这些版本。
	
* 空间使用:
	由于可能会重复安装多个版本的相同依赖,npm 的存储方式可能导致大量的磁盘空间浪费,尤其是在有多个包依赖同一库时。
	
3. pnpm 的存储方式
* 全局存储:
	pnpm 使用全局存储来存放所有包。所有依赖包会被安装到一个共享的位置(通常在用户的主目录下),而项目本身的 node_modules 目录只是存放指向这些全局包的符号链接(symlinks)。
	这样,所有项目都可以通过符号链接访问同一依赖,从而避免重复存储。
	
* 严格的依赖声明:
	pnpm 强制每个包只能直接访问其声明的依赖。这意味着包不会直接访问其父级或其他包的依赖,从而提高了模块的隔离性和可预测性。
	
* 空间使用:
	由于采用了全局存储和符号链接,pnpm 在处理多个项目和依赖时,显著降低了磁盘空间的使用。这使得相同的依赖只需下载一次,无论有多少项目需要使用它。

2.依赖树

1. npm 的依赖树
当使用 npm 安装依赖时,npm 会创建一个层次化的依赖树,每个包的依赖都被单独安装在 node_modules 目录中。主要特点包括:

* 扁平化依赖: 
	npm 会尽量将依赖扁平化。在同一项目中,如果多个包依赖于同一版本的依赖,npm 会将其安装在根 node_modules 目录中。

* 多版本处理: 
	如果不同的依赖包依赖于同一库的不同版本,npm 会在相应的包目录中安装这些版本。这就意味着,一个包可能会存在多个版本的同一依赖,每个版本位于其依赖包的 node_modules 目录中。

* 依赖树结构: 
	依赖树可能看起来像这样:
	└── project
	    ├── packageA
	    │   └── packageB
	    │       └── packageC
	    └── packageD
	        └── packageB
	            └── packageC
	在上述结构中,packageA 和 packageD 都依赖于 packageB,而 packageB 又依赖于 packageC。如果 packageB 需要不同版本的 packageC,则它们会被安装在各自的 node_modules 中。

2. pnpm 的依赖树
pnpm 的依赖处理方式与 npm 有显著不同,主要特点包括:

* 全局存储: 
	pnpm 将所有包安装到一个全局存储位置,实际的项目中只创建符号链接(symlink)指向这个全局存储。这样可以减少磁盘空间的使用。

* 严格依赖管理: 
	pnpm 强制每个包只能访问其直接声明的依赖,这意味着包无法访问其父级或其他包的依赖,确保更加一致和可预测的依赖关系。

* 依赖树结构:
	依赖树可能看起来像这样:
	├── project
	│   ├── node_modules
	│   │   ├── packageA
	│   │   │   └── node_modules
	│   │   │       └── packageB
	│   │   │           └── node_modules
	│   │   │               └── packageC
	│   │   └── packageD
	│   │       └── node_modules
	│   │           └── packageB
	│   │               └── node_modules
	│   │                   └── packageC
	│   └── .pnpm
	└── global storage
	在这个结构中,packageA 和 packageD 仍然依赖于 packageB,但 pnpm 通过全局存储来确保只存储一份 packageB 和 packageC。每个包只能访问它们的直接依赖,从而避免了版本冲突的问题。

三、两者依赖树的差异导致结果的对比

请看以下内容,相信有过一两年的经验,可能使用npm或多或少都会遇到这种情况

  1. 使用npm i 的情况在这里插入图片描述
    上述其实说的问题就是依赖冲突导致不能下载依赖包
    项目中postcss-loader需要安装7.3.4,但另一个依赖要求3.0.0到4.0.0之间,这就是npm依赖树导致的问题,需要人为的手动安装指定版本,或者通过npm install --force 或者 npm install --legacy-peer-deps解决

但是需要注意的是

  • –force:选项强制执行某些操作,即使遇到错误或警告,也会继续执行。使用这个选项可以忽略某些依赖冲突或不符合规范的情况。
  • –legacy-peer-deps:选项使得 npm 在安装时使用旧版的对等依赖行为。具体来说,它允许不严格检查对等依赖的版本冲突。
  1. 使用pnpm i 的情况
    在这里插入图片描述
    在这里插入图片描述
    它会自动处理一些依赖树的关系,也不会存在什么忽略或者强制处理,这样会减少隐藏的一些问题

四、简单说说-g,–save, --save-dev代表着什么

-g / --global:这个选项用于全局安装包。当你希望将包安装到全局环境中,以便在系统的任何地方都能使用时,通常用于命令行工具(CLI)。
–save:将安装的依赖包添加到项目的 package.json 文件的 dependencies 列表中。在 npm 5 之后,默认情况下会自动将依赖保存到 dependencies 中,因此这个选项在现代 npm 使用中不再经常需要。
-D / --save-dev:将安装的包添加到项目的 package.json 文件的 devDependencies 列表中。用于开发过程中需要的工具,例如测试框架、构建工具等,这些工具在生产环境中并不需要。
–save-exact:将安装的包的具体版本(而不是范围版本)保存到 package.json 中。当你希望确保项目在安装时使用确切的版本,而不是可能的较新版本。
–no-save:安装包时不更新 package.json 文件。临时安装某个包用于测试或调试。
–production:仅安装 dependencies 中列出的包,忽略 devDependencies。在生产环境中部署应用程序时使用。
-E / --save-exact:将依赖包的确切版本(不带波浪号或插入符号)保存到 package.json 中。
–legacy-peer-deps:忽略对等依赖的冲突,在安装时使用旧版行为。解决某些依赖冲突问题时使用。
–force:强制执行操作,忽略警告和错误,适用于需要绕过冲突或错误的情况。


总结

以上就是个人收集总结的一些小东西了,给自己总结同时记录,这也就是我为什么偏爱使用pnpm了,因为它会无形中自动解决一些问题,希望对同道中人有点小用啦。。。


http://www.kler.cn/a/590563.html

相关文章:

  • 前端性能优化回答思路
  • 【VUE】ant design vue实现表格table上下拖拽排序
  • 使用 LangGraph 构建智能客服代理系统(DeepSeek 版)
  • 如何启用 HTTPS 并配置免费的 SSL 证书
  • MySQL DBA 运维常用命令
  • STC89C52单片机学习——第22节: LED点阵屏显示图形动画
  • Spring Boot整合JWT 实现双Token机制
  • Maven核心包:maven-resolver-api
  • Netty基础—5.Netty的使用简介
  • 小程序主包方法迁移到分包-调用策略
  • HTB 学习笔记 【中/英】《前端 vs. 后端》P3
  • API接口自动化学习总结
  • 共享 IP 与独立 IP:长期邮件营销的优劣比较
  • 解决QT_Debug 调试信息不输出问题
  • 【笔记】SQL进阶教程(第二版)
  • SpringBoot3+SaToken+JWT:轻量化权限认证实战指南
  • Launcher3 Hotseat区域动态插入All Apps按钮实现方案
  • Elasticsearch搜索引擎 3(DSL)
  • 数学建模:模型求解方法
  • Windows Qt动态监测系统分辨率及缩放比变化