阅读 only-allow

阅读 only-allow

一行代码统一规范包管理器: only-allow,强制在项目上使用特定的包管理器

场景

在实际开发时,往往需要限定包管理器,来保证同样的开发。但是这种通常都是口头相传,并没有强制约束,因此就有了本文的only-allow

only-allow 介绍

Force a specific package manager to be used on a project

强制在项目上使用特定的包管理器。

如:强制使用 yarn

1
2
3
4
5
{
"scripts": {
"preinstall": "npx only-allow yarn"
}
}

注:npm 命令钩子

  • preinstall: 在npm install命令前执行
  • install,postinstall: 在npm install命令后执行

源码

我们通过查看 package.json 文件。

1
2
3
{
"bin": "bin.js"
}

确定入口文件:bin.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env node
const whichPMRuns = require('which-pm-runs');
const boxen = require('boxen');

const argv = process.argv.slice(2);
if (argv.length === 0) {
console.log('Please specify the wanted package manager: only-allow <npm|pnpm|yarn>');
process.exit(1);
}
// 用户规定的包管理器,例如 npx only-allow yarn ,那么wantedPM 为 yarn
const wantedPM = argv[0];
if (wantedPM !== 'npm' && wantedPM !== 'pnpm' && wantedPM !== 'yarn') {
console.log(`"${wantedPM}" is not a valid package manager. Available package managers are: npm, pnpm, or yarn.`);
process.exit(1);
}

// 用户当前安装时 使用的包管理器
const usedPM = whichPMRuns();

// 希望使用的包管理器 不相等,则报错。
// - npm 提示使用 npm install
// - pnpm 提示使用 pnpm install
// - yarn 提示使用 yarn install
// 最后退出进程
if (usedPM && usedPM.name !== wantedPM) {
// boxenOPts: boxen 的配置
// boxen 能让terminal的输出展示盒装的样式,让终端提示更明显
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);
}

其中使用到

  • boxen: 让 terminal的输出展示盒装的样式,让终端提示更明显
  • which-pm-runs: 当前运行的是哪一个包管理器

which-pm-runs 源码

源码比较简单,这里一起讲下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
'use strict';

module.exports = function () {
if (!process.env.npm_config_user_agent) {
return undefined;
}
return pmFromUserAgent(process.env.npm_config_user_agent);
};

// process.env.npm_config_user_agent: pnpm/6.22.2 npm/? node/v14.18.1 darwin x64
// 获取到当前运行脚本的包管理器和版本号
function pmFromUserAgent(userAgent) {
const pmSpec = userAgent.split(' ')[0];
const separatorPos = pmSpec.lastIndexOf('/');
return {
name: pmSpec.substr(0, separatorPos),
version: pmSpec.substr(separatorPos + 1),
};
}

总结

最后,在 only-allow 上可查看本篇源码文章~

参考链接

作者

Sea

发布于

2022-01-25

更新于

2023-01-10

许可协议

评论