1.0.2 • Published 7 years ago

aaron-cli-demo v1.0.2

Weekly downloads
10
License
ISC
Repository
github
Last release
7 years ago

创建自己的 node cli

npm cli , shell 命令 demo

第一步是利用 npm init 创建一个 npm 项目。创建的package.json文件如下:

{
  "name": "aaron-cli-demo",
  "version": "1.0.0",
  "description": "node cli demo",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "npm",
    "node",
    "cli",
    "demo"
  ],
  "author": "aaronflower",
  "license": "ISC"
}

下一步,我们需要写一个 js 脚本文件,根据默认约定命令为 index.js 脚本。

#!/usr/bin/env node
console.log('Hello world, node cli demo')

文件中第一行加上#!释伴(Shebang) 是指名用那个解释程序来执行脚本。

接下来,我们需要在package.json文件中添加一个 bin section,key 值是触发脚本执行的命令, value 是相对于 package.json 文件目录的执行文件。

diff --git a/package.json b/package.json
index 251dd01..9463c11 100644
--- a/package.json
+++ b/package.json
@@ -13,5 +13,8 @@
     "demo"
   ],
   "author": "aaronflower",
-  "license": "ISC"
+  "license": "ISC",
+  "bin": {
+    "aaron-cli": "./index.js"
+  }
 }

现在我们就可以全局安装并测试它了。

$ npm i -g
$ aaron-cli
Hello world, node cli demo

大功告成!

注意: npm install -g 实际上是把脚本软链到 node 的全局 bin 目录下。

$ which aaron-cli
/Users/easonzhan/.nvm/versions/node/v7.5.0/bin/aaron-cli
$ readlink $(which aaron-cli)
../lib/node_modules/aaron-cli-demo/index.js

在开发过程中为了方便可以使用 npm link命令直接链接到我们的开发环境的入口文件。

$ npm link
npm WARN cli-demo@1.0.0 No repository field.
/Users/easonzhan/.nvm/versions/node/v7.5.0/bin/aaron-cli -> /Users/easonzhan/.nvm/versions/node/v7.5.0/lib/node_modules/cli-demo/index.js
/Users/easonzhan/.nvm/versions/node/v7.5.0/lib/node_modules/cli-demo -> /Users/easonzhan/learning/git_repos/node_/npm-aaronflower

可以看出全局的cli-demo已经是链接的我们的开发目录了。

diff --git a/index.js b/index.js
old mode 100644
new mode 100755
index e69de29..55493da
--- a/index.js
+++ b/index.js
@@ -0,0 +1,3 @@
+#!/usr/bin/env node
+console.log('Hello world, node cli demo')
+console.log('use npm link when developing your npm projet')

经过npm link后在命令中执行aaron-cli会直接看到更新。

$ aaron-cli
Hello world, node cli demo
use npm link when developing your npm projet

当脚本都开发完成后,就可以用npm publish把我们的脚本发布到 npm 库上了。然后大家就可以通过 npm 安装使用我们开发的脚本了。

$ npm i -g aaron-cli-demo
# 发布
$ npm adduser # 省略,默认版本是 1.0.0 中的 package.json 中的版本。
$ npm publish # 如果,package.json 中的 description 是空的话,将会用 README.md 来当作描述。
$ npm i -g cli-demo

引入命令行参数解析

对执行脚本时的命令行参数解析,我们可以使用一个很方便的 commander。下面为我们的主程序加上参数解析功能:

|  #!/usr/bin/env node
| -console.log('Hello world, node cli demo')
| -console.log('use npm link when developing your npm projet')
| +var program = require('commander')
| +program
| +     .arguments('<file>')
| +     .option('-u, --username <username>', 'The user to authenticate to')
| +     .option('-p, --password <password>', 'The user\'s password')
| +     .action(function (file) {
| +             console.log('user: %s, password: %s, file: %s', program.username, program.password, file)
| +     })
| +     .parse(process.argv)

接下来我们可发布我们的 cli-demo 啦。一个新的版本。

~/learning/git_repos/node_/npm-aaronflower on  master! ⌚ 23:27:06
$ npm version patch
v1.0.1

~/learning/git_repos/node_/npm-aaronflower on  master! ⌚ 23:28:26
$ npm publish
+ aaron-cli-demo@1.0.1

测试, commander会自动为我们生成 -h, --help 参数哟。

~/learning/git_repos/node_/npm-aaronflower on  master! ⌚ 23:39:07
$ aaron-cli -u aaron --password flower cli-demo-parse.js
user: aaron, password: flower, file: cli-demo-parse.js

~/learning/git_repos/node_/npm-aaronflower on  master! ⌚ 23:39:59
$ aaron-cli -h

  Usage: aaron-cli [options] <file>

  Options:

    -h, --help                 output usage information
    -u, --username <username>  The user to authenticate to
    -p, --password <password>  The user's password

处理用户输入

有些时间脚本也支持用户输入,我们可以使用 process.stdin来处理。但是co-prompt库更加方便使用,co-prompt 是基于 co 来实现的,这样我们就可以使用 ES6 的 yield 语法了。

npm i -S co co-prompt

更新我们的脚本程序:

@@ -1,10 +1,23 @@
-#!/usr/bin/env node
+#!/usr/bin/env node --harmony
+var co = require('co')
+var prompt = require('co-prompt')
 var program = require('commander')
+
 program
        .arguments('<file>')
        .option('-u, --username <username>', 'The user to authenticate to')
        .option('-p, --password <password>', 'The user\'s password')
        .action(function (file) {
-               console.log('user: %s, password: %s, file: %s', program.username, program.password, file)
+               co(function* () {
+                       let username = program.username
+                       let password = program.password
+                       if (!username) {
+                               username = yield prompt('username: ')
+                       }
+                       if (!password) {
+                               password = yield prompt.password('password: ')
+                       }
+                       console.log('user: %s, password: %s, file: %s', username, password, file)
+               })
        })
        .parse(process.argv)

测试,现在我们的命令行参数即支持指定又支持输入了。

~/learning/git_repos/node_/npm-aaronflower on  master! ⌚ 0:08:15
$ aaron-cli -u aaron -p flower foo.js
user: aaron, password: flower, file: foo.js

~/learning/git_repos/node_/npm-aaronflower on  master! ⌚ 0:11:44
$ aaron-cli -u aaron  foo.js
password: *************
user: aaron, password: yesmypassowrd, file: foo.js

~/learning/git_repos/node_/npm-aaronflower on  master! ⌚ 0:11:58
$ aaron-cli  foo.js
username: aaaronflower
password: ******
user: aaaronflower, password: kdiggg, file: foo.js

Links

Building command line tools with Node.js

1.0.2

7 years ago

1.0.1

7 years ago

1.0.0

7 years ago