平常开发中,遇到的各类命令行工具(cli), 如 vue init webpack xxx
, 不少是经过node.js开发的。node.js cli本质其实就是执行node脚本。javascript
首先使用JavaScript编写一个可执行脚本 hellovue
#!/usr/bin/env node
console.log('hello world');
复制代码
而后修改 hello文件的权限 $ chmod 755 hello
,此时就能够执行 hello 了。java
$ ./hello
hello world
复制代码
若是想把 hello 前面的路径去除,须要将 hello 的路径加入到环境变量 PATH。有一种更好的作法就是 使用 npm link
。 在当前目录下新建 package.json ,写入下面的内容。node
{
"name": "hello-cli",
"bin": {
"hello": "hello"
}
}
复制代码
而后执行 npm link 命令,输出 webpack
可见,npm link
建立了2个软连接分别放到系统环境变量$PATH目录里,hello命令和hello-cli模块。 npm link在用户使用的场景下是不须要执行的,用户使用npm i -g hello-cli命令安装便可。git
此时再次执行 hello 时就不用输入路径了。github
hello
hello world
复制代码
最后经过 npm publish
发布到npm官网,就能够供你们安装使用了。web
scripts
指定了运行脚本命令的npm命令行缩写,好比start指定了运行npm run start时,所要执行的命令。 下面的设置指定了npm run preinstall、npm run postinstall、npm run start、npm run test时,所要执行的命令。npm
"scripts": {
"preinstall": "echo here it comes!",
"postinstall": "echo there it goes!",
"start": "node index.js",
"test": "tap test/*.js"
}
复制代码
bin
项用来指定各个内部命令对应的可执行文件的位置。json
"bin": {
"someTool": "./bin/someTool.js"
}
复制代码
上面代码指定,someTool 命令对应的可执行文件为 bin 子目录下的 someTool.js。Npm会寻找这个文件,在node_modules/.bin/目录下创建符号连接。 在上面的例子中,someTool.js会创建符号连接node_modules/.bin/someTool。因为node_modules/.bin/目录会在运行时加入系统的PATH变量, 所以在运行npm时,就能够不带路径,直接经过命令来调用这些脚本。
原生progress.argv
命令行参数能够用系统变量 process.argv
获取。
#!/usr/bin/env node
console.log('hello ', process.argv[2]);
复制代码
执行时,直接在脚本文件后面,加上参数便可。
$ ./hello ben
hello ben
复制代码
其中process为node进程中的全局变量,process.argv为一数组,数组内存储着命令行的各个部分, argv[0]为node的安装路径,argv[1]为主模块文件路径,剩下为子命令或参数,以下:
$ hello a b c
# process.argv的值为[ '/usr/local/bin/node', '/Users/benyasin/Downloads/hello', 'a', 'b', 'c' ]
复制代码
除了上面原始方式以外,还有几个比较流行的工具,好比yargs
与commander
。
yargs
示例:
#!/usr/bin/env node
var argv = require('yargs')
.alias('n', 'name')
.argv;
console.log('hello ', argv.n);
复制代码
能够经过空格
或=
的方式进行赋值。还能够使用alias指定别名。
$ hello -n tom
hello tom
$ hello --name tom
hello tom
$ hello --name=tom
hello tom
复制代码
commander
#!/usr/bin/env node
const program = require('commander');
program
.option('-n, --name', 'your name', 'ben')
.parse(process.argv);
console.log('hello', program.name);
复制代码
执行命令行程序的方式以下:
$ hello -n tom
hello tom
$ hello --name
hello ben
复制代码
用法: .option('-n, --name <name>', 'description info', 'default value')
除了option
外,还有几个经常使用的api:version
、command
、parse
、outputHelp
。更多使用细节请参照其官方文档。
除了上述的yargs
或commander
外,编写命令行工具一般还会用到其它一些第三方模块,好比:
inquirer
: 命令行交互界面集合。能够提问,解析输入,校验回答等ora
: 能够使终端输出更优雅,设置正在进行,成功或失败chalk
: 能够对终端输出的文字设置一些颜色等样式有时还会用到download-git-repo
,好比开发一个脚本架工具,在初始化项目时,须要实时地从github上拉取最新的项目模板。 这里推荐一个智能合约的脚本架工具robin,有兴趣的同窗能够参考一下它的实现。