从 1 到完美,用 node 写一个命令行工具
1. package.json
中的 bin
字段
现在,不管是前端项目还是 node
项目,一般都会用 npm
做包管理工具,而 package.json
是其相关的配置信息。
对 node
项目而言,模块导出入口文件由 package.json
的 main
字段指定,而如果是要安装到命令行的工具,则是由 package.json
的 bin
字段指定。
1.1 配置单个命令
与包名同名
-
{
-
"name": "pro",
-
"bin": "bin/pro.js"
-
}
这样安装的命令名称就是 pro
。
自定义命令名称(与包名不同名)
-
{
-
"name": "pro-cli",
-
"bin": {
-
"pro": "bin/pro.js"
-
}
-
}
这样安装的命令名称也是 pro
。
1.2 配置多个命令
-
{
-
"name": "pro-cli",
-
"bin": {
-
"pro": "bin/pro.js",
-
"mini": "bin/mini.js"
-
}
-
}
这样安装就有 pro
与 mini
两个命令。
2. 对应 bin/pro.js
文件的写法
-
#!/usr/bin/env node
-
-
require('../lib/pro');
与普通的 js
文件写法一样,只是前面要加上 #!/usr/bin/env node
。
这段前缀代码叫 shebang
,具体可以参考 Shebang (Unix) - Wikipedia。
3. 安装方式
3.1 全局安装
-
npm i -g pro-cli
这种安装方式可以在命令行全局使用。
-
pro dev
-
-
pro build
3.2 本地安装
-
npm i --save-dev pro-cli
这种安装方式需要配合 npm
一起使用,比如:
-
# package.json
-
{
-
"scripts": {
-
"dev": "pro dev",
-
"build": "pro build"
-
}
-
}
-
-
# 使用
-
npm run dev
-
npm run build
4. 选择合适的命令行封装库
一般来说,一个命令都会有如下的一些参数:
-
-v,--version
或-V,--version
:查看版本号 -
-h,--help
:查看帮助信息
如果完全自己来写的,就会很麻烦,尤其是帮助信息。所以,选择一个好的命令行封装库,能够帮我们省去很多工作。
用的比较多的:
-
commander.js
-
yargs
-
meow
以 commander.js
为例。
4.1 安装
-
npm install commander --save
4.2 注册
-
const commander = require('commander');
注册版本号与描述:
-
commander
-
.version('0.0.1')
-
.description('A cli application named pro');
注册参数(非子命令参数):
-
commander
-
.option('-p, --peppers', 'Add peppers')
-
.option('-P, --pineapple', 'Add pineapple')
-
.option('-b, --bbq-sauce', 'Add bbq sauce')
-
.option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
注册子命令:
-
commander
-
.command('rm <dir>')
-
.option('-r, --recursive', 'Remove recursively')
-
.action((dir, cmd) => {
-
console.log('remove ' + dir + (cmd.recursive ? ' recursively' : ''))
-
})
解析:
-
commander.parse(process.argv);
4.3 使用
查看版本号:
-
pro -V
-
pro --version
-
-
# 打印结果
-
0.0.1
运行 rm
子命令:
-
pro rm dir
查看帮助( commander
会自动生成):
-
pro -h
-
pro --help
-
-
# 打印结果
-
Usage: pro [options]
-
-
A cli application named pro
-
-
Options:
-
-h, --help output usage information
-
-V, --version output the version number
-
-p, --peppers Add peppers
-
-P, --pineapple Add pineapple
-
-b, --bbq Add bbq sauce
-
-c, --cheese <type> Add the specified type of cheese [marble]
-
-C, --no-cheese You do not want any cheese
更多用法查看 commander.js。
5. 常用的命令行相关工具库
5.1 minimist 解析命令行的参数
-
var argv = require('minimist')(process.argv.slice(2));
-
console.dir(argv);
-
$ node example/parse.js -a beep -b boop
-
{ _: [], a: 'beep', b: 'boop' }
-
$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
-
{ _: [ 'foo', 'bar', 'baz' ],
-
x: 3,
-
y: 4,
-
n: 5,
-
a: true,
-
b: true,
-
c: true,
-
beep: 'boop' }
更多参考 minimist。
5.2 chalk: 让命令行的字符带上颜色
更多参考 chalk。
5.3 Inquirer.js 让命令行与用户进行交互,如输入、选择等。
更多参考 Inquirer.js。
5.4 shelljs 跨平台 Unix shell 命令 的 node 封装
-
var shell = require('shelljs');
-
-
if (!shell.which('git')) {
-
shell.echo('Sorry, this script requires git');
-
shell.exit(1);
-
}
-
-
// Copy files to release dir
-
shell.rm('-rf', 'out/Release');
-
shell.cp('-R', 'stuff/', 'out/Release');
-
-
// Replace macros in each .js file
-
shell.cd('lib');
-
shell.ls('*.js').forEach(function (file) {
-
shell.sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
-
shell.sed('-i', /^.*REMOVE_THIS_LINE.*$/, '', file);
-
shell.sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, shell.cat('macro.js'), file);
-
});
-
shell.cd('..');
-
-
// Run external tool synchronously
-
if (shell.exec('git commit -am "Auto-commit"').code !== 0) {
-
shell.echo('Error: Git commit failed');
-
shell.exit(1);
-
}
更多参考 shelljs。
5.5 blessed-contrib 命令行图表
更多参考 blessed-contrib。
5.6 cash 跨平台 linux 命令 的 node 封装
与 shelljs 功能差不多。
-
const $ = require('cash');
-
const out = $.ls('.', {l: true});
更多参考 cash。
5.7 prompts 又一个让命令行与用户进行交互的工具
与 Inquirer.js 功能差不多。
更多参考 prompts。
5.8 ora 命令行加载中图标
更多参考 ora。
5.9 progress 命令行进度条
-
downloading [===== ] 39/bps 29% 3.7s
更多参考 progress。
5.10 更多
更多关于命令行的工具库可以参考 command-line-utilities。
6. 比较常用的命令行 APP
命令行相关的应用就很多啦,比如 babel
、 webpack
、 rollup
、 eslint
等,但这些不仅仅是命令行工具。
下面介绍一些纯命令行应用:
-
vtop: 美美的 linux top 命令界面
-
speed-test: 测试网络链接速度
-
http-server: 零配置启动一个 http 服务器
-
fkill-cli: 跨平台 kill 命令
更多纯命令行应用可以参考 command-line-apps。
原文发布时间为:2018-10-13
本文作者:senntyou