type
status
date
slug
summary
tags
category
icon
password
😀
在前端项目的开发过程当中,往往会引用到各种各样的第三方库,而这些第三方库的安装和管理就需要使用到包管理工具,本文主要记录一下近些年来我使用到的三款主流的 node 包管理工具 npm、yarn、pnpm
 
 
yarn:特点扁平化依赖(有些包是有包跟包之间的依赖关系,所以再最开始安装之前就去解析了一遍所有的依赖相),并行安装,本地缓存

📝 NPM

npm 是 node 默认的包管理工具(自带),npm 被大家诟病最多的就是安装包的速度非常慢

npm 为什么安装包很慢

  1. 默认情况下,npm 从一个名为 https://registry.npmjs.org/ 的服务器上下包。这个服务器在国外,因此下包速度会非常慢。所以很多人都会将 npm 的镜像源修改为淘宝源
  1. npm2 采用的是 node_modules 嵌套模式,即每个包都会有自己独立的 node_modules ,且会将各自依赖进行安装,依赖的依赖也会产生自己的 node_modules ,这样就产生了“嵌套依赖”。这种方式的优点是模块依赖关系清晰。 缺点也比较明显:
  • 依赖层级太深,会导致文件路径过长的问题,尤其在 window 系统下,最多260多个字符。
  • 大量重复的包被安装,文件体积超级大。比如有两个第三方库都依赖于同一个版本的 lodash,那么 lodash 会分别在两者的 node_modules 中被安装,也就是重复安装。
  • 模块实例不能共享。比如 React 有一些内部变量,在两个不同包引入的 React 不是同一个模块实例,因此无法共享内部变量,导致一些不可预知的 bug。

📝 YARN

yarn 是 facebook 推出的 node 包管理工具,主要用来解决 npm2 一些已知的问题,比如说,不支持离线模式、树形结构的嵌套依赖、依赖版本不一致问题……

Yarn 优点

  1. 离线模式:如果一个 package 之前已经安装过,yarn 会直接从缓存中获取,而不是重新下载
  1. 依赖版本一致性:在每一台机器上针对同一个项目安装依赖时,生成的依赖关系顺序和版本是一致的。
notion image
以上图为例,一个项目依赖 A, B, C 三个库,在编写 package.json 的时候,给 A, B, C 都指定了版本号。但是 A 库可能又依赖 D, E, F 库,D 库又依赖 G, H 库。这么多关联依赖关系中,很可能某个库在指定依赖时,没有指定版本号。这就会导致了在另一台机器上对同样的工程安装依赖,或者把这台机器工程下的 node_modules 目录删除来重新安装依赖。由于关联依赖中,没有指定版本号的库,发生了版本更新,就会导致再次安装的依赖,其中具体某些软件包的版本是不一致的。
yarn 采用的解决方式是,引入了一个 yarn.lock 文件来应对这个问题。lock 机制在很多包管理中都有用到。yarn.lock 会记录你安装的所有大大小小的软件包的具体版本号。只要你不删除 yarn.lock 文件,再次运行 yarn install 时,会根据其中记录的版本号获取所有依赖包。你可以把 yarn.lock 提交到版本库里,这样在其他机器拉取项目代码并运行 yarn install 时,可以保证安装的依赖都是完全一致的。
  1. 扁平化模式:当项目关联依赖中包括对某个包的重复引用,在实际安装时将尽量避免重复的创建。就不会出现 npm 中同一个包被安装多次的情况。
  1. 并行安装:npm 是需要等待前一个依赖完全安装完才跳到后一个依赖继续处理,而 yarn 则可并行执行包。

📝 PNPM

 
2017 年 pnpm 推出。全称 Performance NPM,即高性能的 npm。它主要通过共享依赖(软连接)来减少磁盘空间占用,并通过硬链接来加快安装速度。是目前 node 包管理工具的最优解
 

软、硬链接基本概念

在计算机中我们文件夹中的文件实际上是一个指针,但这个指针并不是直接指向我们在磁盘中存储文件的位置,而是指向一个 inode 块,inode 中存储着文件在磁盘中的各种信息,一般我们的文件都是指向对应文件的 inode,我们把这类链接成为硬链接,但是还有一种链接,它存储的并不是实际的值,而是另一个硬链接的地址,我们把这类链接成为软链接。
 

软、硬链接作用

比如说执行 npm install express,那么 express 包和它的依赖都会被下载下来,导致 node_modules 非常庞大,然而安装 node 的寻找包的规则,这些包都是可以在项目中直接被引用的,也就是说我们在项目中引用了未在 package.json 中声明的包,这显然是不安全的,这种情况也被称为幽灵依赖。
notion image
 
pnpm 使用软连接就能解决以上问题,下图可以看到 node_modules 只有 express,并没有幽灵依赖。但是这个 express 文件夹只是一个软链接, 它的真正存储的地方在图中的 .pnpm 文件夹中。
notion image
 
从 .pnpm 文件夹可以看出来所有的依赖都在这里铺平了,都是从全局 store 硬连接过来的,然后包和包之间的依赖关系是通过软链接组织的。
notion image
说白了 pnpm 的实现原理就是一个包全局只保存一份,剩下的都是软硬连接,节省磁盘空间。其次就是快,因为通过链接的方式而不是复制,自然会快。
 
Mac系统上nvm安装与使用ThreeJS 屏幕坐标与世界坐标互转