乐趣区

关于前端:包管理工具之npm也慌了

npm 也慌了?

起因

因为 npm 的种种问题,我很早就换成了 pnpm 和 yarn(然而其实 npm 也在应用),曾经很久没有关注 npm 的性能更新了。最近无意间进入 Node18 版本的装置目录,发现其除了惯例的 node,npm 等默认装置了一个新的包corepack,这个就是明天我要分享的货色了。

注: 我因为 18 版本的 node 上发现了这个包,目前最新 lts 曾经是 20 了,最新都 21 了。起初去追溯其历史发现其曾经在 14.21.3 上就有了,然而 14.0.0 没有,没再具体去查。

这是一个什么货色呢?来看看官网介绍。

Corepack 是一个零运行时依赖的 Node.js 脚本,用作 Node.js 我的项目与其开发过程中所需的软件包管理器之间的桥梁。从理论角度来看,Corepack 容许您在 不装置Yarn、npm 和 pnpm 的状况下应用它们。

在构建软件包时,只需像平时一样应用您的包管理器即可。在 Yarn 我的项目中运行,在 pnpm 我的项目中运行,在 npm 我的项目中运行。Corepack 将捕捉这些调用,并依据状况进行解决:

  1. 如果本地我的项目已配置您要应用的包管理器,Corepack 将静默地下载并缓存最新的兼容版本。
  2. 如果本地我的项目配置的是不同的包管理器,Corepack 将要求您应用正确的包管理器再次运行命令,从而防止毁坏您的安装文件。
  3. 如果本地我的项目没有配置任何包管理器,Corepack 将假设您晓得本人在做什么,并应用作为“已知良好版本”的固定包管理器版本。

我之前发过一篇文章说了从 npm 到 yarn,再到 pnpm 的历史和我集体的一些了解,不理解的能够去看看。简略来说,因为一些大牛不满 npm 的性能或者不满其模块组织形式,或者不满其它什么中央,造了一个有一个轮子,在持续应用 npm 仓库源的根底上产生了比拟闻名的 yarn 以及 pnpm。尽管 npm 感觉到压力,不断改进本人的毛病,学习其它工具的长处,然而用户必定还是被分流不少,而后以下是我的猜想:预计 npm 发现也阻止不了用户的分流了,打不过就退出,你爱用啥用啥,我间接出一个包管理工具的管理工具,另辟蹊径,我间接去治理 npm,pnpm 以及 yarn。这个工具就是Corepack.

Corepack 是一种简化 Node.js 我的项目依赖治理的工具,它提供了一种便捷的形式,使您能够在开发过程中应用不同的包管理器,如 Yarn、npm 和 pnpm,而无需当时装置它们 。通过应用Corepack,您能够在我的项目中间接运行相似于yarn installnpm installpnpm install等命令,而不用放心在开发环境中装置和配置这些包管理器。

总结一下:

  1. npm 又造轮子了,这个轮子用来治理 npm,yarn 和 pnpm,联合 package.json 配置,咱们能够限定我的项目要应用的工具。
  2. 对立包管理器,不必手动保护包管理器,间接应用反对的包管理器命令即可。看官网介绍那段文字,咱们不须要装置 yarn 和 pnpm 状况下也能用 yarn 和 pnpm?

Corepack

启用

咱们上边官网介绍那一段,有一句话 容许您在不装置 Yarn、npm 和 pnpm 的状况下应用它们 。这句话其实通知咱们很重要的事,以前咱们装置完 node,而后须要应用 pnpm 或者 yarn,那么须要顺次装置一遍。而从 node 引入Corepack 后,看意思不须要再去装置了(当然不是 node 默认曾经装置了,而是用的时会去静默下载安装到 Corepack 模块外部)。那么怎么用呢?

因为 Corepack 可能还处于 Experimental 阶段,所以性能默认是敞开的,须要咱们明确开启能力应用,它将在二进制文件旁边设置环境中的符号链接(并在必要时笼罩现有的符号链接)。

# 开启
corepack enable
corepack enable npm #npm 须要独自开启,不倡议开启

#敞开
corepack disable
corepack disable npm #npm 须要独自敞开,不倡议开启,如果开启了,敞开也无奈还原初始状态,而是删除了 corepack 外面的链接

留神:

  1. corepack enable 开启后默认会装置 yarn 和 pnpm 的最新版,如果您的 node 版本是 14,yarn 或者 pnpm 的最新版可能要求会比 14 高,这就陷入一个你启用了,应用时又说你版本太低的问题。我是间接 18 上装置的。
  2. 这里留神一下,npm 还是比拟无耻的,它要治理 yarn 和 pnpm,然而 npm 有点特权(兴许是因为处于测试阶段或者本人 npm 的版本兼容问题),npm 也要启用须要独自执行 corepack enable npm,去替换图中的全局 npm 的软链,不然咱们后边应用它治理时就会发现,yarn 和 pnpm 都能够阻止,它本人畅行无阻。( 这外面还有个大坑,这个命令审慎操作,请看前面 问题 1 )
  3. 倡议不要开启 corepack enable npm。起因有上面 问题 1 ,还有一个问题就是如果你应用 nvm 或者一些进入目录,可能你设置了一些默认执行 npm 命令的一些脚本,例如 nvm 主动切换等等,一旦你配置的包管理器是 pnpm 或者yarn,那么 npm 必定会执行报错。可能还有其它各种各样的奇怪问题。

我以 Node v18.0.0 为例,在咱们未开启时,就是下面第一张图。当咱们执行完开启命令:

发现主动链接了 pnpm 和 yarn 的执行脚本,而后你应用 yarn 或者 pnpm 命令时,会主动在 corepack 目录下载对应工具版本。

咱们也发现 npm 还是原来的模块地址,它不会被动更换链接,除非你执行corepack enable npm

我也能了解为啥官网手动装置提醒外面,让先卸载本人装置的 yarn 和 pnpm,因为它会本人下载(然而要留神网络)。

下载和缓存反对的包管理器最新版(全局环境)

corepack prepare --all

切换到指定版本

corepack prepare pnpm@<version> --activate

在 node16.17 后,反对 latest 下载最新版本

corepack prepare pnpm@<version> --activate

应用

这一步,咱们才开始真正应用 Corepack 的能力。

咱们当初某个我的项目想只应用 pnpm,然而有时候包管理器太多,忘了进去就 yarn 或者 npm,导致产生了不同的依赖构造以及 lock 文件等等。那么请在 package.json 中增加 packageManager 字段。(packageManager 后边工具必须指定版本且如同必须指定语义化版本,即 x.y.z 模式,这就比拟坑了,我看 issis 有人提这个问题了,看看官网会不会放开)

例如:

{
  "name": "test",
  "version": "3.8.6",
  "description": "test",
  "author": "DLLCNX",
  "private": true,
  "packageManager": "pnpm@7.23.0",
  "scripts": {
    "dev": "vite",
    "build:prod": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "pinia": "2.0.22",
    "vue": "3.2.45",
    "vue-cropper": "1.0.3",
    "vue-router": "4.1.4"
  },
  "devDependencies": {}}

而后咱们在此我的项目下应用 npm 和 yarn 以及 pnpm:

yarn 和 npm 不让应用,pnpm 能够失常应用。(此处留神,npm 下面说过你须要独自开启,不然此处 npm 仍旧能够应用)

问题

1. Segmentation fault

问题:
开启 corepack enable npm 后,应用 npm 时,呈现 Segmentation fault

起因简述:

因为 corepack 版本是随着 node 版本公布的。一旦在 corepack@<=0.18.0,而npm@>9.7.0 时,如果开启 npm 治理,就会报Segmentation fault,如同存在不兼容。fix: disable v8-compile-cache when using npm@>=9.7.0 by merceyz · Pull Request #276 · nodejs/corepack (github.com)

解决办法:

执行 npm install -g corepack 降级 corepack 即可,截止 2024 年 2 月,最新版是corepack@0.25.2,反对Node v18.17.1 || >=20.10.0

然而:

然而我发现我本人的 Node 版本是 Node v18.12.1,我如果装置 corepack@0.25.2,三个命令因为 node 版本和 corepack 不匹配都用不了。而corepack@0.19.0 能够应用,然而它会把 npm 链接到 10.4.0 版本。(难堪)

上一步,咱们执行降级能够解决问题,然而有一个问题。例如我是 Node v18.2.1,其对应npm v8.19.2。一旦我执行corepack enable npm 强行开启 npm 治理,那么我如果发现报错了,想降级 corepack,后果因为执行不了 npm 命令,无奈降级,即便执行corepack disabled 敞开也不行,陷入了死循环。

所以

如果 Node 18 以下版本倡议还是别开启 corepack enable npm 了,太折腾了,开启 yarn 和 pnpm 即可。

如果版本是 18,倡议间接应用 18 的最新版本 Node v18.19.1。

提醒最举荐间接应用 Node 最新版,毕竟 corepack 随着版本也在更新公布。

2. node v14 开启 corepack 后应用 yarn 报版本问题

起因简述:

因为 corepack 默认装置了 yarn 和 pnpm 的最新版,而最新版 yarn 或者 pnpm 的 node 版本要求可能高于 14。

解决办法: 利用以下命令切换适宜的版本

corepack prepare yarn@x.y.z --activate  # 切换数字版本
#或
corepack prepare yarn@1 --activate  # 切换 1 版本
#或
corepack prepare yarn@stable --activate  # 切换最新版
3. 开启 corepack 后,执行失败Internal Error

其实会去网络下载 pnpm 和 yarn,如果也开启 npm,同理睬去下载 npm,可能会因为网络下载失败。

多试几次,或者看看官网缓存策略,官网环境变量外面能够设置拜访 url 地址,然而发现国内用的淘宝镜像地址因为是重定向模式,目前无奈用。环境变量

4. 如果没网环境呢

在有网机器上,把管理器缓存导出到 tgz 文件,在没有网的环境中导入,如下:

# 导出
corepack prepare --all -o corepack.tgz

# 导入
corepack hydrate corepack.tgz

ni

咱们通过 corepack 能够限度咱们应用什么管理器,然而还能不能再不便点,这边在 corepack 的根底上举荐一个其它工具ni

ni – 应用正确的包管理工具

下面,咱们应用 corepack 以及配合在 package.josn 中增加的 packageManager 限定字段,让咱们能够在某个我的项目中指定应用哪个包管理器,一旦应用其它的就会报正告并进行执行。那么,有没有一个工具,主动去辨认我的设置,默认执行我的包管理器呢?

那么,ni 可能适宜你。它会依据你我的项目中的锁文件或者 packageManager 配置,自动识别管理工具。corepack目前只反对 npm、pnpm 以及 yarn,而 ni 是反对后面三个根底上,还反对 bun(新的工具,认命了,覆灭吧)。

装置

npm i -g @antfu/ni

应用

ni 其实相当于利用它本人的命令替换几个包管理器对应的命令,所以如果要让它默认执行,其实相当于你要用它的代替命令。

首先,咱们要有一个的前提。ni 假设您应用锁文件(必须得有,当初新版不论 npm 还是 pnpm,还是 yarn 执行依赖加载时其实都会产生,所以除非本人刻意解决,个别不会有问题)。

在它运行之前,它将在你的我的项目目录检测你的以后包管理器(或 packageManager 字段),yarn.lockpnpm-lock.yamlpackage-lock.jsonbun.lockbpackageManager。而后默认去运行相应的包命令

那么命令都有啥?

ni – install
ni

# npm install
# yarn install
# pnpm install
# bun install

以下面装置依赖命令为例,咱们间接在我的项目目录输出 ni 执行,它会依据本人检索到的 lock 文件或者配置,应用对应的包管理工具去执行下载,上面的命令同理。以我下面配置过 packageManager 的我的项目为例,间接执行 ni,能够看到间接应用 pnpm 开干了。

ni vite

# npm i vite
# yarn add vite
# pnpm add vite
# bun add vite
ni @types/node -D

# npm i @types/node -D
# yarn add @types/node -D
# pnpm add -D @types/node
# bun add -d @types/node
ni --frozen

# npm ci
# yarn install --frozen-lockfile (Yarn 1)
# yarn install --immutable (Yarn Berry)
# pnpm install --frozen-lockfile
# bun install --no-save
ni -g eslint

# npm i -g eslint
# yarn global add eslint (Yarn 1)
# pnpm add -g eslint
# bun add -g eslint

# 这个应用默认配置,而不是以后的工作目录检索的工具
nr – run
nr dev --port=3000

# npm run dev -- --port=3000
# yarn run dev --port=3000
# pnpm run dev --port=3000
# bun run dev --port=3000
nr

# 交互式地抉择要运行的脚本
# supports https://www.npmjs.com/package/npm-scripts-info convention
nr -

# 从新运行最初一个命令
nlx – download & execute
nlx vitest

# npx vitest
# yarn dlx vitest
# pnpm dlx vitest
# bunx vitest
nu – upgrade
nu

# npm upgrade
# yarn upgrade (Yarn 1)
# yarn up (Yarn Berry)
# pnpm update
# bun update
nu -i

# (not available for npm & bun)
# yarn upgrade-interactive (Yarn 1)
# yarn up -i (Yarn Berry)
# pnpm update -i
nun – uninstall
nun webpack

# npm uninstall webpack
# yarn remove webpack
# pnpm remove webpack
# bun remove webpack
nun -g silent

# npm uninstall -g silent
# yarn global remove silent
# pnpm remove -g silent
# bun remove -g silent
nci – clean install
nci

# npm ci
# yarn install --frozen-lockfile
# pnpm install --frozen-lockfile
# bun install --no-save

如果不存在相应的管理器,则此命令将在此过程中全局装置它。

na – agent alias
na

# npm
# yarn
# pnpm
# bun
na run foo

# npm run foo
# yarn run foo
# pnpm run foo
# bun run foo

问题

  1. 执行程序

    咱们上边说了,ni 会去检测我的项目目录的 lock 文件,而后抉择应用哪个工具。然而,如果几个包管理工具锁文件都有呢?

    通过验证:

    • 如果 package.josn 设置了 packageManager 参数,那么以其指定的工具为准。
    • 如果没有 packageManager 限定工具,会从 pnpm->yarn->npm 顺次检索 lock 文件。

相干文章

包管理工具之从 NPM 到 PNPM(https://dllcnx:18888/2024/01/81af97faf393/)

包管理工具之仓库源管理工具 nrm(https://dllcnx:18888/2021/11/a05b75568d68/)

退出移动版