Corepack同一管理JS包管理器版本在日常的开发过程中我们前端常常与两个东西打交道node和包管理器(npm、yar
前言
在日常的开发过程中我们前端常常与两个东西打交道node和包管理器(npm、yarn、pnpm)。项目从远程拉取后如果运行报错,我们就会问同事你的node是什么版本的,包管理器的版本是什么版本的。还有一种是很生气的事,项目下明明有package-lock.json文件,他就是要用yarn安装。
正文
node版本的事好解决,一般只要使用nvm切几个版本试下就行了,我就在16和18版本之间切换。有的项目会在 package.json 文件中使用 engines 字段来指定项目所需的 Node版本
{
"engines": {
"node": ">=14.17.0"
}
}
现在来说说Corepack是什么,我们通常情况下需要用到哪一个包管理器就在全局装一下(npm i -g yarn等),这样很麻烦。使用nvm切换一下node还要在重新安装一下。Corepack的设计目标之一就是让开发者无需全局安装 yarn、pnpm 等包管理器,而是通过 Corepack 来管理和使用这些包管理器的特定版本。
使用方法
Corepack新增在node版本16.9.0和14.19.0后。
- 启用 Corepack。
只要这一行命令之后,就相当于使用Corepack来管理包管理器了(运行一次就可以),运行后在控制台输入 yarn --version等,都是有对应的版本信息返回的(不同的node版本,默认yarn、pnpm的版本也是不一样),你在全局不需要安装。
corepack enable
我们可以来看一下corepack enable后是如何有yarn、pnpm。我们可以到node安装目录下找到corepack.js文件
module.exports = JSON.parse('{"definitions":{"npm":{"default":"7.20.1","transparent":{"commands":[["npm","init"],["npx"]]},"ranges":{"*":{"url":"https://registry.npmjs.org/npm/-/npm-{}.tgz","bin":{"npm":"./bin/npm-cli.js","npx":"./bin/npx-cli.js"},"registry":{"type":"npm","package":"npm"}}}},"pnpm":{"default":"6.11.0","transparent":{"commands":[["pnpm","init"],["pnpx"]]},"ranges":{"<6.0.0":{"url":"https://registry.npmjs.org/pnpm/-/pnpm-{}.tgz","bin":{"pnpm":"./bin/pnpm.js","pnpx":"./bin/pnpx.js"},"registry":{"type":"npm","package":"pnpm"}},">=6.0.0":{"url":"https://registry.npmjs.org/pnpm/-/pnpm-{}.tgz","bin":{"pnpm":"./bin/pnpm.cjs","pnpx":"./bin/pnpx.cjs"},"registry":{"type":"npm","package":"pnpm"}}}},"yarn":{"default":"1.22.15","transparent":{"default":"3.0.0","commands":[["yarn","dlx"]]},"ranges":{"<2.0.0":{"url":"https://registry.yarnpkg.com/yarn/-/yarn-{}.tgz","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"registry":{"type":"npm","package":"yarn"}},">=2.0.0":{"name":"yarn","url":"https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js","bin":["yarn","yarnpkg"],"registry":{"type":"url","url":"https://repo.yarnpkg.com/tags","fields":{"tags":"latest","versions":"tags"}}}}}}}');
可以看到default字段这就是默认下载的版本。接下来看"url": "https://registry.yarnpkg.com/yarn/-/yarn-{}.tgz",Corepack通过把url中的{}替换成版本号来进行下载。
{
"definitions": {
"npm": {
"default": "7.20.1",
"transparent": {
"commands": [
[
"npm",
"init"
],
[
"npx"
]
]
},
"ranges": {
"*": {
"url": "https://registry.npmjs.org/npm/-/npm-{}.tgz",
"bin": {
"npm": "./bin/npm-cli.js",
"npx": "./bin/npx-cli.js"
},
"registry": {
"type": "npm",
"package": "npm"
}
}
}
},
"pnpm": {
"default": "6.11.0",
"transparent": {
"commands": [
[
"pnpm",
"init"
],
[
"pnpx"
]
]
},
"ranges": {
"<6.0.0": {
"url": "https://registry.npmjs.org/pnpm/-/pnpm-{}.tgz",
"bin": {
"pnpm": "./bin/pnpm.js",
"pnpx": "./bin/pnpx.js"
},
"registry": {
"type": "npm",
"package": "pnpm"
}
},
">=6.0.0": {
"url": "https://registry.npmjs.org/pnpm/-/pnpm-{}.tgz",
"bin": {
"pnpm": "./bin/pnpm.cjs",
"pnpx": "./bin/pnpx.cjs"
},
"registry": {
"type": "npm",
"package": "pnpm"
}
}
}
},
"yarn": {
"default": "1.22.15",
"transparent": {
"default": "3.0.0",
"commands": [
[
"yarn",
"dlx"
]
]
},
"ranges": {
"<2.0.0": {
"url": "https://registry.yarnpkg.com/yarn/-/yarn-{}.tgz",
"bin": {
"yarn": "./bin/yarn.js",
"yarnpkg": "./bin/yarn.js"
},
"registry": {
"type": "npm",
"package": "yarn"
}
},
">=2.0.0": {
"name": "yarn",
"url": "https://repo.yarnpkg.com/{}/packages/yarnpkg-cli/bin/yarn.js",
"bin": [
"yarn",
"yarnpkg"
],
"registry": {
"type": "url",
"url": "https://repo.yarnpkg.com/tags",
"fields": {
"tags": "latest",
"versions": "tags"
}
}
}
}
}
}
}
- 禁用 Corepack
corepack disable
如何配合package.json同一包管理器和版本
启用Corepack并在项目package.json 文件中新增属性 packageManager属性。
"packageManager": "pnpm@8.15.5"
当我们使用yarn时,就会提示然让我们使用pnpm

当我们使用在项目下查看包管理器版本和不在项目下查看包管理器版本,两者是不同的。一个是我们packageManager指定的版本一个是corepack默认安装的版本

有人说为什么不用only-allow配合preinstallHook来限制包管理器,因为现在好像有bug,都是在依赖安装以后才执行,那我依赖都装完了,你再检查有什么用呢。
Corepack对于npm的限制
Corepack对npm开了后门,当你使用启用Corepack后,在项目中还是可以使用npm i,你需要单独设置 npm
corepack enable npm
这样才会限制npm

但是这个命令有bug,我试了一下node在版本17.9.1及以上corepack enable npm 是没有问题的。版本以下使用corepack enable npm 后你npm命令就废了,什么都干不了,不知道为什么,你只能把这个版本的node卸载,重新安装(相当于重置了一下)。

结语
官网链接 Corepack | Node.js v22.3.0 Documentation (nodejs.org)
大家可以去试试
转载自:https://juejin.cn/post/7386505099848859702