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

包管理器-npm、yarn、cnpm、pnpm的比较

1. npm (node package manage)

1.1本地安装

使用命令:npm install 包名 或 npm i 包名
本地安装的包出现在当前目录下的node_module目录中
如果本地安装的包带有CLI,npm 会将它的CLI脚本放置到node_modules/.bin下,使用npx命令即可调用。

1.2 全局安装

全局安装的包放置在一个特殊的全局目录。
使用命令npm install --global 包名 或 npm i -g 包名。
全局安装的包并非所有工程可用,它仅提供全局的 CLI 工具。大部分情况下,都不需要全局安装包。

1.3 安装命令

依赖到生产环境
npm i 包名
npm i --save 包名
npm i -S 包名
安装依赖到开发环境
npm i --save-dev 包名
npm i -D 包名

1.4. 当使用nodejs导入模块时,如果模块路径不是以 ./ 或 …/ 开头,则 node 会认为导入的模块来自于 node_modules 目录。
1.5. npm脚本

在package.json的script字段配置常用的CLI命令,使用 npm run 脚本名称运行脚本。在脚本中可以省略npx。

2. npm过去存在的问题:

  • 依赖目录嵌套层次深:过去npm的依赖是嵌套的,windows系统无法支持太深的目录。
  • 下载速度慢:由于嵌套层次深,包的下载只能是串行的;多个相同版本的包重复下载。
  • 控制台输出繁杂:打印很多包的详细信息
  • 工程移植问题:以前只有package.json配置文件,没有package-lock.json文件

3. yarn的出现,因为它具有以下优势:

  • 使用扁平的目录结构
  • 并行下载
  • 使用本地缓存
  • 精简控制台输出信息,只输出关键信息
  • 使用yarn-lock文件记录确切的依赖

4. 受到yarn的影响,npm6借鉴了yarn的先进理念,做出了以下优化:

  • 目录扁平化
  • 并行下载
  • 本地缓存
  • 使用package-lock.json记录确切的依赖
  • 增加了大量的命令别名
  • 内置npx,可以启动本地CLI工具
  • 极大的简化了控制台输出

5. cnpm

npm的registry服务器在国外,可能导致下载缓慢或失败。过去npm没有提供修改registry的功能,淘宝搭建了自己的registry,即淘宝npm镜像,淘宝还提供了一个CLI工具cnpm,其他使用和npm基本相同。

6. pnpm

  • 同npm和yarn一样,仍然使用缓存来保存已经安装过的包。使用pnpm-lock.yaml记录详细的依赖版本
  • 不同于yarn和npm,pnpm使用符号链接和硬链接的做法来放置依赖,避免的文件的拷贝,提高了安装效率,也极大的降低了磁盘空间的占用。
  • 由于使用了符号链接和硬链接,pnpm可以规避windows系统路径过长的问题,因此它使用树形依赖。因为树形依赖,项目只能使用直接依賴,不能使用间接依赖。

7. pnpm原理:

  • 文件的本质:文件实际是一个指针,指向外部存储地址(硬盘、U盘)。删除文件实际是删除指针,所以速度很快。
  • 文件的拷贝:将文件指针指向内容复制一份,然后产生一个新的指针指向新的内容。
  • 硬链接:将一个文件A指针复制到另一个文件B指针中,文件B就是文件A的硬链接。
  • 符号链接(软连接):为某个文件或文件夹A创建符号链接B,则B指向A。
  • 快捷方式:类似于符号链接,式windows早期支持的链接方式,不仅是一个指针,还包含了权限、兼容性、启动方式等各种信息。快捷方式是windows系统独有的,不跨平台使用。

符号链接和硬链接的区别

  • 硬链接只能链接文件,符号链接可以连接文件和目录。
  • 硬链接在连接完成后仅和文件内容关联,和之前的链接没有关系了。符号链接始终和之前的链接的文件关联,和内容文件不直接关联。

相关文章:

  • JDK安装详细教程(以JDK17为例)
  • c++将utf8转gb2312
  • Tomcat组件概念和请求流程
  • 【Redis】初识 Redis
  • [JS]认识feach
  • 设计模式的七大原则
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • 【Linux】进程间通信——命名管道和共享内存
  • 2024年公共文化与社会服务国际会议(ICPCSS 2024)
  • 事务的学习
  • C#小结:未能找到类型或命名空间名“xxx”(是否缺少 using 指令或程序集引用?)
  • 容器docker 架构命令案例
  • 文心快码——百度研发编码助手
  • 大模型/NLP/算法面试题总结3——BERT和T5的区别?
  • WindowsMac共享文件夹设置
  • SegmentFault for Android 3.0 发布
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • C学习-枚举(九)
  •  D - 粉碎叛乱F - 其他起义
  • ECMAScript6(0):ES6简明参考手册
  • JAVA 学习IO流
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • JavaScript 一些 DOM 的知识点
  • JS学习笔记——闭包
  • learning koa2.x
  • MYSQL 的 IF 函数
  • mysql_config not found
  • MySQL-事务管理(基础)
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • SpriteKit 技巧之添加背景图片
  • Travix是如何部署应用程序到Kubernetes上的
  • Vue2 SSR 的优化之旅
  • 产品三维模型在线预览
  • 全栈开发——Linux
  • 微信公众号开发小记——5.python微信红包
  • RDS-Mysql 物理备份恢复到本地数据库上
  • #知识分享#笔记#学习方法
  • $.ajax()
  • (02)vite环境变量配置
  • (04)odoo视图操作
  • (1)svelte 教程:hello world
  • (2)nginx 安装、启停
  • (附源码)php投票系统 毕业设计 121500
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (五十)第 7 章 图(有向图的十字链表存储)
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .Net Winform开发笔记(一)
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .Net6 Api Swagger配置
  • .NET8 动态添加定时任务(CRON Expression, Whatever)
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • ?.的用法
  • @angular/cli项目构建--Dynamic.Form