背景
现在前端包管理工具有npm、yarn、pnpm,在多人协作的项目中,大家一般会约定用其中一种工具,如果团队加入了新同学,使用其他包管理工具进行安装和提交。就有可能改变项目依赖版本,造成一些不可预见的问题。
所以我们需要一个工具,在代码层面强制规定使用哪一个包管理工具,only-allow用途便于此
npm 脚本钩子
“scripts”要为部分中定义的任何脚本创建“pre”或“post”脚本 package.json,只需创建另一个 具有匹配名称的脚本并将“pre”或“post”添加到它们的开头
{
"scripts": {
"precompress": "{{ executes BEFORE the `compress` script }}",
"compress": "{{ run command to compress files }}",
"postcompress": "{{ executes AFTER `compress` script }}"
}
}
简单来说它的执行过程等于
npm run precompress && npm run compress && npm run postcompress
- 常用npm脚本内置钩子
- prepublish:在打包和发布包之前运行,也可以在本地运行,npm install不带任何参数。(见下文)
- prepare:在打包和发布包之前运行,在本地npm install不带任何参数,以及安装 git 依赖项时(见下文)。这是在之后运行prepublish,但在之前prepublishOnly。
- publish, postpublish:在包发布后运行。
- preinstall:在安装包之前运行
- install, postinstall:安装包后运行。
- preuninstall, uninstall:在卸载包之前运行。
- postuninstall:在软件包卸载后运行。
- preversion:在升级包版本之前运行。
- version:在更新包版本之后运行,但在提交之前。
- postversion:在更新包版本和提交之后运行。
only-allow
安装
pnpm install only-allow -D
使用
在看umi源码中可以发现,只需要在scripts中添加preinstall钩子即可通过only-allow强制使用pnpm为当前项目的包管理工具"scripts": {
"preinstall": "npx only-allow pnpm",
},
源码
```javascript!/usr/bin/env node
// which-pm-runs返回包管理器和版本 const whichPMRuns = require(‘which-pm-runs’) // boxen终端打印样式 const boxen = require(‘boxen’)
const argv = process.argv.slice(2)
if (argv.length === 0) {
console.log(‘Please specify the wanted package manager: only-allow "${wantedPM}" is not a valid package manager. Available package managers are: npm, pnpm, or yarn.
)
process.exit(1)
}
const usedPM = whichPMRuns() // 如果不是用户想要的包管理工具,则报错、退出进程 if (usedPM && usedPM.name !== wantedPM) { const boxenOpts = { borderColor: ‘red’, borderStyle: ‘double’, padding: 1 } switch (wantedPM) { case ‘npm’: console.log(boxen(‘Use “npm install” for installation in this project’, boxenOpts)) break case ‘pnpm’: console.log(boxen(`Use “pnpm install” for installation in this project.
If you don’t have pnpm, install it via “npm i -g pnpm”. For more details, go to https://pnpm.js.org/`, boxenOpts)) break case ‘yarn’: console.log(boxen(`Use “yarn” for installation in this project.
If you don’t have Yarn, install it via “npm i -g yarn”. For more details, go to https://yarnpkg.com/`, boxenOpts)) break } process.exit(1) }
``` only-allow 期待的包管理器和运行的包管理器对比。匹配失败,则提示并报错。而which-pm-runs 通过获取 process.env.npm_config_user_agent 变量获取到当前运行脚本的包管理器和版本号