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将捕捉这些调用,并依据状况进行解决:
- 如果本地我的项目已配置您要应用的包管理器,Corepack将静默地下载并缓存最新的兼容版本。
- 如果本地我的项目配置的是不同的包管理器,Corepack将要求您应用正确的包管理器再次运行命令,从而防止毁坏您的安装文件。
- 如果本地我的项目没有配置任何包管理器,Corepack将假设您晓得本人在做什么,并应用作为“已知良好版本”的固定包管理器版本。
我之前发过一篇文章说了从npm到yarn,再到pnpm的历史和我集体的一些了解,不理解的能够去看看。简略来说,因为一些大牛不满npm的性能或者不满其模块组织形式,或者不满其它什么中央,造了一个有一个轮子,在持续应用npm仓库源的根底上产生了比拟闻名的yarn以及pnpm。尽管npm感觉到压力,不断改进本人的毛病,学习其它工具的长处,然而用户必定还是被分流不少,而后以下是我的猜想:预计npm发现也阻止不了用户的分流了,打不过就退出,你爱用啥用啥,我间接出一个包管理工具的管理工具,另辟蹊径,我间接去治理npm,pnpm以及yarn。这个工具就是Corepack
.
Corepack是一种简化Node.js我的项目依赖治理的工具,它提供了一种便捷的形式,使您能够在开发过程中应用不同的包管理器,如Yarn、npm和pnpm,而无需当时装置它们。通过应用Corepack
,您能够在我的项目中间接运行相似于yarn install
、npm install
或pnpm install
等命令,而不用放心在开发环境中装置和配置这些包管理器。
总结一下:
- npm又造轮子了,这个轮子用来治理npm,yarn和pnpm,联合package.json配置,咱们能够限定我的项目要应用的工具。
- 对立包管理器,不必手动保护包管理器,间接应用反对的包管理器命令即可。看官网介绍那段文字,咱们不须要装置yarn和pnpm状况下也能用yarn和pnpm?
Corepack
启用
咱们上边官网介绍那一段,有一句话容许您在不装置Yarn、npm和pnpm的状况下应用它们
。这句话其实通知咱们很重要的事,以前咱们装置完node,而后须要应用pnpm或者yarn,那么须要顺次装置一遍。而从node引入Corepack
后,看意思不须要再去装置了(当然不是node默认曾经装置了,而是用的时会去静默下载安装到Corepack模块外部)。那么怎么用呢?
因为Corepack
可能还处于Experimental阶段,所以性能默认是敞开的,须要咱们明确开启能力应用,它将在二进制文件旁边设置环境中的符号链接 (并在必要时笼罩现有的符号链接)。
#开启corepack enablecorepack enable npm #npm须要独自开启,不倡议开启#敞开corepack disablecorepack disable npm #npm须要独自敞开,不倡议开启,如果开启了,敞开也无奈还原初始状态,而是删除了corepack外面的链接
留神:
- corepack enable开启后默认会装置yarn和pnpm的最新版,如果您的node版本是14,yarn或者pnpm的最新版可能要求会比14高,这就陷入一个你启用了,应用时又说你版本太低的问题。我是间接18上装置的。
- 这里留神一下,npm还是比拟无耻的,它要治理yarn和pnpm,然而npm有点特权(兴许是因为处于测试阶段或者本人npm的版本兼容问题),npm也要启用须要独自执行corepack enable npm,去替换图中的全局npm的软链,不然咱们后边应用它治理时就会发现,yarn和pnpm都能够阻止,它本人畅行无阻。(这外面还有个大坑,这个命令审慎操作,请看前面
问题1
) - 倡议不要开启
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.lock
、pnpm-lock.yaml
、package-lock.json
、bun.lockb
、packageManager
。而后默认去运行相应的包命令
那么命令都有啥?
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
问题
执行程序
咱们上边说了,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/)