美文网首页
npm、yarn、pnpm包管理器

npm、yarn、pnpm包管理器

作者: 一蓑烟雨任平生_cui | 来源:发表于2022-11-04 19:35 被阅读0次

    npm yarn pnpm 都是包管理器。

    npm

    早期 npm3 之前存在的问题:

    1. 依赖嵌套过深,导致文件路径过长,有时候在 window 上删除 node_modules 包时提示文件路径过长删除失败
    2. 重复安装造成的 node_modules 体积过大,安装速度慢

    npm 和 npx

    npm 是包管理器

    npx 是 npm 5.2 以后新增的一个命令,可以执行远程模块或者项目 node_modules 中的 CLI 程序。

    yarn

    yarn 解决了 npm 存在的问题

    1. 缓存、多线程并行安装(解决安装速度慢)
    2. 扁平化(解决嵌套结构造成的文件路径过长) npm3 以后也使用扁平结构

    此外还加了新特性:

    1. Monorepo 支持,一般需要配合 learn 优化流程
    2. 离线缓存,本地会保存一份副本
    3. lock 文件,npm5+也增加了 lock 文件

    版本格式

    npm 包采用语义化格式

    a.b.c 语义:

    1. a 代表主版本号,做了不兼容的 API 修改
    2. b 次版本号,做了向下兼容的功能性新增
    3. c 修订号,做了向下兼容的问题修正

    版本号只是一个理想化的约定,具体包是否遵循不是包使用者控制的。默认情况下安装依赖时,得到的版本号是类似于 ^1.0.0 格式。代表安装主版本为 1 的最新包。

    所以通过 lock 文件锁定包的版本号。

    扁平化缺点

    1. 扁平化依赖树的算法是耗时的 IO 操作
    2. 深层依赖包必须复制到项目 node_modules 根目录
    3. 幽灵依赖,项目中可以直接使用依赖的包的包。造成的问题是,删除依赖后,依赖的包也删除,导致项目中出现包找不到的问题。造成项目所依赖的包不清晰
    4. npm 分身

    pnpm

    pnpm 是 npm 的替代品。

    优势

    1. 安装速度快、效率高
    2. 更少的磁盘占用
    3. 创建非扁平的 node_modules 目录

    pnpm 安装的依赖包都存放在本机磁盘上统一的位置,通过 pnpm 安装包时不是从远程下载,也不是本机复制(yarn 可以离线缓存),而是通过创建硬链接的方式使用全局存储的包,省去了下载的时间;此外,无论有多少个项目使用同样的包,都 hard link 到全局 store。

    1. 对于同一依赖包的不同版本,只存放有差异的文件
    2. 安装包时,所有文件都会硬连接到包存放的位置,而不会下载占用额外空间

    当使用 npm 或 yarn classic 安装时,所有依赖的包全部提升到 node_modules 根目录下。带来的问题就是项目中可以使用本不属于项目依赖的包,出现幽灵依赖。

    默认情况,pnpm 通过符号链接的方式仅将项目的直接依赖安装到 node_modules 根目录下。

    硬连接和软连接(符号链接)

    hard link(硬链接):多个文件名指向同一索引节点。硬链接的作用之一是允许一个文件拥有多个有效路径名,这样就可以建立硬链接到重要的文件,以防止“误删”源数据。

    sybolic link(软链接,也叫符号链接): 类似于 windows 系统中的快捷方式。符号链接是以相对或绝对路径而不是实际内容的形式引用原始文件夹/文件的文件。在这种情况下,它们用于将路径名解析影响到正确的位置。

    通过软连接解决幽灵依赖
    通过硬连接解决重复下载

    image.png

    以上图为 axios 例:

    node_modules 下的 axios 只是一个 symlink。axios 的实际位置是node_modules/.pnpmaxios@1.1.3/node_modules/axios , 而该 axios 又是一个 hard link,link 在全局 store。axios 的依赖也存在该目录,也只是一个 symlink,也是 link 在 .pnpm 下。

    所以 .pnpm 是一个虚拟存储目录,以扁平化的形式存储所有包,每个包都以可以在 .pnpm/<name>@<version>/node_modules/<name> 格式的文件夹中找到。

    对于不同包所依赖的版本不同的相同包(比如:A 依赖 C1.0,B 依赖 C.20),pnpm 是将不同版本放在同一层级里,通过符号链接选择加载的版本,而 yarn 是放在不同层级,依赖递归查找算法来选择版本。

    pnpm 通过 symlink ➕ 扁平化(包扁平化到.pnpm 虚拟存储目录)的方式解决了深层嵌套的问题。通过 hard link 的方式解决了重复安装包所占用磁盘的问题。

    安装 pkg

    安装依赖包

     pnpm install
    

    参数:

    -r

    将递归安装 workspace 中所有目录的依赖。默认为 true。即执行pnpm i相当于执行 pnpm i -r

    安装单个包

    pnpm add <pkg>
    pnpm add vue -w -D
    
    1. -D 开发依赖
    2. -w (--workspace-root 或 --ignore-workspace-root-check) 将包安装在项目的根目录下

    如果需要安装成扁平化,.npmrc 文件中配置shamefully-hoist = true

    参数

    -w (--workspace-root 或 --ignore-workspace-root-check)

    将包安装到项目根目录下

    --workspace

    仅添加能在 workspace 中找到的依赖包

    pnpm add --workspace @cui_test/shared --filter @cui_test/reactivity
    

    将 packages 下的的 shared 包安装到 reactivity 下

    -F(--filter)

    安装到 packages 目录下指定的包名下,例如:将 dayjs 安装到 foo 目录下:

    # @cui_test/foo 为packages下的pkg name
    
    pnpm add dayjs -F @cui_test/foo
    
    -r(--recursive)

    递归查找,例如:将 workspace 下的 shared 包安装到 foo 下:

    pnpm add @cui_test/shared -r -F @cui_test/foo
    
    image.png

    .npmrc

    pnpm 使用 npm 一样的配置格式。.npmrc 的一些常见配置。比如:

    registry

    配置代理地址:

    registry=https://tapobao.com/
    

    recursive-install

    指定 pnpm i-r 参数

    engine-strict

    如果启用,pnpm 将不会安装任何声称与当前 Node 版本不兼容的包。默认 false

    shamefully-hoist

    pnpm 创建的是非扁平的 node_modules 目录。如果需要处理成扁平化,配置 shamefully-hoist = true

    CI/CD 安装策略

    npm

    npm install 和 npm ci

    都可以安装依赖包

    npm install

    1. 安装项目依赖
    2. 可以安装单个依赖
    3. package.json 和 package-lock.json 版本号不一致后会更新 package-lock.json

    npm ci

    npm cinpm clean-install的简称。ci代表“持续集成”,旨在用于 CI/CD 环境。执行 npm ci 必须存在 package-lock.json 文件,安装前会删除 node_modules 目录。安装时不会使用缓存,npm ci是安装模块的最干净和最安全的方式。如果需要使用缓存,使用 npm install

    特点

    1. 项目必须存在 package-lock.json 或 npm-shrinkwrap.json 文件才能执行 npm ci
    2. 如果依赖项在 package-lock.json 和 package.json 中的版本号不一致,npm ci 会显示错误并中断安装
    3. npm ci 一次只能安装整个项目的依赖,不能安装单个依赖
    4. npm ci 安装之前会先删除 node_modules 文件夹,所以项目不存在 node_modules 或者目录为空会加快安装速度

    使用 npm ci 构建可重现的节点

    场景

    用于自动化环境,比如 CI/CD。目的是确保对依赖项进行全新安装,而且严格按照 package-lock.json 中指定的版本安装,不会更新 lock 版本号,防止出现依赖版本不一致造成的故障。

    pnpm i --frozen-lockfile

    等效于 npm ci。不会更新 pnpm-lock.yaml

    Monorepo

    monorepo 是管理多个项目的 git 仓库。

    通过 workspace 实现对 Monorepo 的支持。npm7+、yarn 都支持 monorepo。重点关注 pnpm 对 monorepo 的支持。

    pnpm workspace

    pnpm 一开始就支持 workspace,只需在项目根目录创建 pnpm-workspace.yaml 文件。

    packages:
      - 'packages/*'
    

    关于 pnpm的优势不止是安装速度快,节省磁盘,现代计算机貌似都不在乎这些,重要的是天然的支持 monorepo,且用法及其简单。

    相关文章

      网友评论

          本文标题:npm、yarn、pnpm包管理器

          本文链接:https://www.haomeiwen.com/subject/hyjutdtx.html