杜绝使用 npm

2022-02-13  本文已影响0人  littleyu

管理器

npm

node 自带

为什么 node 要选择 npm?
在远古时代,前端是通过网址来共享代码,比如你想使用 jQuery,那么你点击 jQuery 网站上提供的链接就可以下载 jQuery,放到自己的网站上使用。
但是当项目的依赖越来越多的时候,这是一件很麻烦的事情,去 jQuery 官网下载 jQuery,去 BootStrap 官网下载 BootStrap...等等。
程序员 Isaac Z. Schlueter 给出一个解决方案:用一个工具把这些代码集中到一起来管理吧!毕竟懒才是程序员的第一生产力。

NPM 的思路大概是这样的:
发展

yarn

安装 yarn

首先不推荐使用 npm 安装
为什么?

  • Yarn 团队认为 npm 不安全且不可靠,根据Yarn项目维护者的说法,通过npm安装Yarn违反了项目目标,可能会引起问题,并且通常比特定于平台的安装方法更糟糕。
  • 一般不推荐通过 npm 安装 Yarn。使用 npm 安装 Yarn 是不确定的,包没有签名,唯一执行的完整性检查是基本的 SHA1 哈希,这在安装系统范围的应用程序时是一个安全风险。
  • 通过 npm 运行 Yarn,它是一个单独的包管理器实用程序,可能会导致边缘问题(请参阅issue 2072
  • 通过系统包管理器安装将 Yarn 与 npm 分离,允许您在没有 npm 的情况下运行 Yarn
  • 系统包管理器通常会定期运行,保持 Yarn 更新
  • 通过 npm 安装 Yarn 很

但是从 Yarn 2.x 开始,Yarn 团队改变了他们的建议,现在建议通过 npm 安装该工具。此建议围绕锁定每个项目使用的 Yarn 版本的优势。这使项目能够适应不同版本的 Yarn 的变化。

pnpm(performant npm)

安装 pnpm

npm i -g pnpm

详解

安装时

执行命令后,首先会构建依赖树,然后针对每个节点下的包,会经历下面四个步骤:

  1. 将依赖包的版本区间解析为某个具体的版本号
  2. 下载对应版本依赖的 tar 包到本地离线镜像(能够在无网环境下安装,npm 5+ 才抄袭过来)
  3. 将依赖从离线镜像解压到本地缓存
  4. 将依赖从缓存拷贝到当前目录的 node_modules 目录

然后,对应的包就会到达项目的node_modules当中。

速度

很明显 npm 是最慢的。
为什么慢,因为 node_modules,文件小而多,磁盘 I/O 的特别慢,而且重复下载的文件也会在有多。

包管理方式

依赖版本

"dependencies": {
  "vue": "^3.2.6"
}
// package-lock.json,npm 是 json 文件,方便看得懂
"vue": {
  "version": "3.2.6",   
  "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.6.tgz",   //下载路径
  "integrity": "sha512-Zlb3LMemQS3Xxa6xPsecu45bNjr1hxO8Bh5FUmE0Dr6Ot0znZBKiM47rK6O7FTcakxOnvVN+NTXWJF6u8ajpCQ==",   
  "requires": {
    "@vue/compiler-dom": "3.2.6",
    "@vue/runtime-dom": "3.2.6",
    "@vue/shared": "3.2.6"
  }
}

目录结构

# ① 假设项目依赖a,b,c三个模块,依赖树为:
#  +- a
#    +- react@15
#  +- b
#    +- react@16
#  +- c
#    +- react@16
# yarn安装时会按照项目被依赖的次数作为权重,将依赖提升(hoisting),
# 安装后的node_modules结构为:
  .
  └── node_modules
      ├── a
      │   ├── index.js
      │   ├── node_modules
      │   │   └── react  # @15
      │   └── package.json
      ├── b
      │   ├── index.js
      │   └── package.json
      ├── c
      │   ├── index.js
      │   └── package.json
      └── react  # @16 被依赖了两次,所以进行提升
# ② 现在假设在①的基础上,根项目依赖了react@15,对于项目自己的依赖肯定是要放在node_modules根目录的,
# 由于一个目录下不能存在同名目录,所以react@16没有的提升机会. 
# 安装后node_moduels结构为
  .
  └── node_modules
      ├── a
      │   ├── index.js
      │   └── package.json # react@15 提升
      ├── b
      │   ├── index.js
      │   ├── node_modules
      │   │   └── react  # @16
      │   └── package.json
      ├── c
      │   ├── index.js
      │   ├── node_modules
      │   │   └── react  # @16
      │   └── package.json
      └── react  # @15
# 上面的结果可以看出,react@16出现了重复
  .
  └── node_modules
      ├── a
      │   ├── index.js
      │   ├── node_modules
      │   │   └── react  # @16
      │   └── package.json
      ├── b
      │   ├── index.js
      │   ├── node_modules
      │   │   └── react  # @15
      │   └── package.json
      └── react  # @15 or 16?
# 答案是: 都有可能。取决于 a 和 b 在 package.json中的位置,如果 a 声明在前面,那么就是提升的就是 react@16,否则是react@15。
  .
  └── node_modules
  │    ├── .pnpm
  │    ├── react
  │    ├── .modules.yaml
  └── package.json
  └── pnpm-lock.yaml # lockfiles
  .
  └── node_modules
        ├── .pnpm
              ├ node_modules
              ├ registry.npmjs.org+@js+tokens@4.0.0
              ├ .......
              ├ registry.npmjs.org+react@17.0.2
                  ├ node_modules
                      ├ loose-envify (软链接)
                      ├ ... (软链接)
                      ├ react
                        ├ cjs
                        ├ umd
                        ├ ......

monorepo

目前我们为什么使用 yarn

上一篇下一篇

猜你喜欢

热点阅读