从 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 noderequire(’../lib/pro’);与普通的 js 文件写法一样,只是前面要加上 #!/usr/bin/env node。这段前缀代码叫 shebang,具体可以参考 Shebang (Unix) - Wikipedia).3. 安装方式3.1 全局安装npm i -g pro-cli这种安装方式可以在命令行全局使用。pro devpro build3.2 本地安装npm i –save-dev pro-cli这种安装方式需要配合 npm 一起使用,比如:# package.json{ “scripts”: { “dev”: “pro dev”, “build”: “pro build” }}# 使用npm run devnpm run build4. 选择合适的命令行封装库一般来说,一个命令都会有如下的一些参数:-v, –version 或 -V, –version: 查看版本号-h, –help: 查看帮助信息如果完全自己来写的,就会很麻烦,尤其是帮助信息。所以,选择一个好的命令行封装库,能够帮我们省去很多工作。用的比较多的:commander.jsyargsmeow以 commander.js 为例:4.1 安装npm install commander –save4.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 -Vpro –version# 打印结果0.0.1运行 rm 子命令pro rm dir查看帮助(commander 会自动生成)pro -hpro –help# 打印结果Usage: pro [options]A cli application named proOptions: -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 dirshell.rm(’-rf’, ‘out/Release’);shell.cp(’-R’, ‘stuff/’, ‘out/Release’);// Replace macros in each .js fileshell.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 synchronouslyif (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。后续更多博客,查看 https://github.com/senntyou/blogs作者:深予之 (@senntyou)版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)