用node開發repl應用

每次看到一些庫npm -g install xx而後,執行xx就能夠跑起來,這不就是一個shell工具了嗎,那麼我不就能夠不用學習shell語法,直接用js寫命令行腳本了嗎!html

所謂的repl應用就是一個終端命令行工具,若是使用linux對於命令行工具例如curl,awk,grep,find,這些確定不陌生,而如今,咱們就是用node去寫相似這樣的程序前端

對於第一次動手寫repl應用,咱們首先,瞭解一些知識點.node

文檔 http://nodejs.org/api/process.htmllinux

process 對象在node裏面是全局對象,不須要用require引入,直接使用git

console.log(process)github

咱們就能夠在終端裏面看到process都有些什麼內容了.對於,開發一個repl應用,咱們對於process對象只須要了解如下下幾點就行web

  • process.argv //此次輸入值集合
  • process.stdout.* //終端輸出方法
  • process.stdin.* //終端輸入方法
  • process.exit(); // 退出

對於process的瞭解這幾點大部分repl應用均可以開發了,接下來,咱們說說,如何讓命令行工具讀取參數.shell

對於repl而言,值讀取的常見的通常有兩種:npm

配置值

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env node
if(process.argv[2] === '-w'){
    var args = process.argv.slice(3);
    var output = '';
    args.forEach(function (item){
        output += item + ' ';
    })
    console.log(output);
    process.exit();
}

node repl.js -w Hello world!json

Hello world!

交互式

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env node
function read(prompt) {
    process.stdout.write(prompt + ':');
    process.stdin.resume();
    process.stdin.setEncoding('utf-8');
    process.stdin.on('data', function(chunk) {
      process.stdout.write('output: ' + chunk);
      process.exit();
    });
}

read('input')

node repl.js

input: Hello world!

output: Hello world!

repl 應用本質其實就是一個shell腳本,如今咱們要用node來寫,因此,對於*nix環境咱們必須在第一行說明咱們的文件須要在什麼環境下運行.

#!/usr/bin/env node

process.argv

咱們主要從命令行輸入值都是從process.argv裏面讀取,這個對象,保存了咱們全部命令行的輸入,咱們能夠打印出來看看

console.log(`process.argv)

1
2
3
4
[ 'node',
  'E:\\ProjectGitHub\\node.js\\repl.js',
  '-w',
  'Helloworld!' ]

從這個輸出咱們就能夠很明瞭的知道咱們爲何要用process.argv.slice(3);來獲取值了.

process.stdout && process.stdin

這兩個方法用於對終端輸出和輸入的操做,上面的例子應該很好演示這個使用了,這裏就再也不贅述了.

實戰演練

如今要講的這個repl應用就是簡單的在終端中顯示前端亂燉的專欄列表.效果以下(PS:綠色那些是debug輸出,你自動忽略吧...):

輸入 htmljs article 輸入 htmljs article -p 1

效果圖

內容準備

這裏用到了request,cheerio 對前端亂燉頁面進行解析,這塊的討論已經超出了本文的討論範圍,之後放在介紹cheerio的時候再說這塊的實現.

用命令行看前端亂燉專欄列表:

https://github.com/youxiachai/html-js-cli

利用Commander處理輸入

對於如何在終端輸入參數,在上面的讀取篇已經所有介紹完畢,用原生process處理輸入異常的繁瑣,對於這點,TJ大神寫了一個模塊commander用來處理.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env node

var program = require('commander'),
    htmljscli = require('../index'),
    libInfo = require('../package');

program
    .version(libInfo.version)

program
    .command('article')
    .description('show article list')
    .option('-p, --page [page]', 'article list')
    .action(function(options){
        htmljscli.listArticle(options.page)
    });


program.parse(process.argv); // 這行必須是結尾

不到20行代碼就能夠解決了本來須要各類處理process.argv 狀況,並且還很貼心了幫咱們自動生成help介紹

htmljs article -h

效果圖

使用commander 咱們只須要了解一下幾點就能夠了

  • commander.option()

用於將對象值對象化, 例如上文定義的commander .option('-p, --page [page]', 'article list')咱們輸入的時候-p 的時候,就能夠用options.page 獲取咱們的參數

  • commander.command().option().action()

用於配置子命令

有時候,一些庫會要求咱們

npm -g install cnpm

而後很神奇的發現能夠

cnpm install xx

這類的操做,那咱們發佈的包怎麼實現這個神奇的魔法呢.原理很是簡單,咱們只須要在咱們的package.json加入如下幾句就行

1
2
3
4
5
{
  "bin": {
    "htmljs": "./bin/htmljscli"
  }
}

npm 安裝的時候就會自動與當前系統環境進行綁定.

接下來咱們只須要

npm -g install html-js-cli

運行

htmljs article

就能夠在終端看到專欄列表了

值得注意的時候,在windows發佈你寫node repl應用,*nix用戶安裝的時候,命令並不會起做用,因此,要用npm發佈repl應用的時候請使用*nix系統

https://github.com/turingou/douban.fm

http://justan.github.io/twei/

https://github.com/cnpm/cnpm

相關文章
相關標籤/搜索