開發一個Node命令列小玩具全過程--高顏統計工具

藍色的秋風發表於2018-08-14

背景

命令列工具對於我們來說非常的熟悉,一些命令列的操作也極大的簡化了我們的日常工作。本文就基於我寫的一個Node命令列程式碼計數器來進行展開。

相信熟悉linux系統的,對於一些ps,grep,cp,mv…等命令用起來應該愛不釋手,這也是我想要開發一個便捷命令列的初衷,其次就是記錄一個完整開源小玩具的全過程。

命令列的特點:

  • 操作簡便
  • 可視性強

看了一下當前的一些命令列有以下問題

因此這一款高顏值方便的統計工具誕生。

開發一個Node命令列小玩具全過程--高顏統計工具

高顏圖

開發一個Node命令列小玩具全過程--高顏統計工具

玩具原始碼

github.com/hua1995116/…

準備

第三方庫

  • cli-table
  • colors
  • commander
  • ignore

dev庫(用來測試)

  • chai
  • mocha
  • codecov
  • istanbu

Node相容性

  • babel

靜態檔案

  • 語言對映庫
  • 顏色庫

思路

開發一個Node命令列小玩具全過程--高顏統計工具

通過commander來獲取使用者的一些自定義配置

program
    .version('0.1.0')
    .option('-i, --ignore [dir]', 'ignore dir')
    .option('-p, --path [dir]', 'ignore dir')
    .parse(process.argv);

複製程式碼

Node遍歷檔案,每種語言行數資訊

function getFile(dirPath) {

    const files = fs.readdirSync(dirPath);

    files.forEach((item) => {
        ...
    })
}
                  
複製程式碼

ignore過濾輸出到cache

function handleIgnode(cPath) {
    try {
        const currentPath = path.join(ROOTPATH, '.gitignore');
        const fileData = fs.readFileSync(currentPath, 'utf-8');
        const ignoreList = fileData.split('\n');
        const filterList = filterData(ignoreList);
        const ig = ignore().add(filterList);
        return ig.ignores(cPath);
    } catch (e) {
        return false;
    }
}
複製程式碼

遍歷cache,統計max-line,進行colors

function hanldeTable(){
    ...
    if (maxCount < langInfo[item].totalLines) {
        maxCount = langInfo[item].totalLines;
        maxIndex = index;
    }
    ...
}
複製程式碼

cli-table 輸出展示

function outputTbale() {
    const {
        header,
        content,
        bottom
    } = initTable();

    const {
        totalFiles,
        totalCode,
        totalBlank,
        tablesContent
    } = hanldeTable();

	...

    console.log(`T=${totalTime} s`, `(${fileSpeed} files/s`, `${lineSpeed} lines/s)`)
    console.log(header.toString())
    console.log(content.toString())
    console.log(bottom.toString())
}
複製程式碼

改進

loading

對於多檔案目錄,提供loading

lass StreamLoad {
    constructor(option) {
        this.stream = option.stream;
        this.text = option.text;
        this.clearLine = 0;
    }
    setValue(value) {
        this.text = value;
        this.render();
    }
    render() {
        this.clear();
        this.clearLine++;
        this.stream.write(`read ${this.text} file\n`);
    }
    clear() {
        if(!this.stream.isTTY) {
            return this;
        }
        
        for (let i = 0; i < this.clearLine; i++) {
            this.stream.moveCursor(0, -1);
            this.stream.clearLine();
			this.stream.cursorTo(0);
        }
        this.clearLine = 0;
    }
}

const progress = new StreamLoad({
    stream: process.stderr,
    text: 0
})

複製程式碼

建立了一個實現loading的類。主要用到readline中的處理方法,詳見nodejs.org/dist/latest…

babel

對於低版本node的相容

cnpm i babel-cli
複製程式碼

package.json

"build": "./node_modules/.bin/babel src --out-dir lib"
複製程式碼

測試用例

chai,mocha

用來測試遍歷檔案是否正確

const path = require('path');
const assert = require('chai').assert;

const {getFileData} = require('../src/linec');

describe('linec files test', () => {
    it('can linec dir', () => {
        const url = path.join(__dirname, '../example');
        console.log(url);

        const dirObj = JSON.stringify(getFileData(url));

        const expectData = '{"CSS":{"file":1,"blankLines":0,"totalLines":4,"color":"#563d7c"},"JavaScript":{"file":1,"blankLines":0,"totalLines":1,"color":"#f1e05a"},"JSON":{"file":1,"blankLines":0,"totalLines":3,"color":"#fff"},"Markdown":{"file":1,"blankLines":0,"totalLines":1,"color":"#fff"}}';

        assert.equal(dirObj, expectData);

    })
})
複製程式碼

執行

./node_modules/mocha/bin/mocha
複製程式碼

本專案中還新增了程式碼覆蓋率的測試,因此是這樣的

"test": "./node_modules/.bin/istanbul cover node_modules/mocha/bin/_mocha && ./node_modules/.bin/codecov",
複製程式碼

釋出

Step1

開啟https://www.npmjs.com/signup

開發一個Node命令列小玩具全過程--高顏統計工具

註冊一個賬號

step2

如果有賬號直接到這一步

npm login
複製程式碼

step3

在package.json中介入version

{
  "name": "linec",
  "version": "1.2.4",
  "description": "line count",
  "main": "index.js",
  ...
}

複製程式碼

step4

npm publish
複製程式碼

Tip:注意每次發版需要更改package.json 中的version,不然會發版失敗哦。

命令列

package.json

"bin": {
	"linec": "./lib/index.js"
},
複製程式碼

本地專案命令列

npm link
複製程式碼

就可以使用linec 命令,將linec命令軟連線到本地,linec這個名字可以自定義。

遠端命令列

預設就是包名字,但是如果bin裡面定義了一個名字,同上,可以修改名字。也就是包名可以和命令不一致,但是為了更方便的使用,個人建議統一包名和命令。

詳情可以參考 www.ruanyifeng.com/blog/2015/0…

持續整合測試&覆蓋率的自動統計

travis-ci.org/

配置.travis.yml

language: node_js

node_js:
  - "stable"

sudo: false

before_script:
  - npm install
複製程式碼

這個是我的配置,每次你的提交,只要含有npm run test命令,travis會自動呼叫,自動檢測。

travis還有個好處,在別人給你提交pr的時候,可以自動執行測試用例,避免一些低階錯誤的發生。以下就是效果圖。

開發一個Node命令列小玩具全過程--高顏統計工具

codecov.io/gh

這是一個統計程式碼覆蓋率的工具,在npm run test中新增他,在pr的時候可以看到覆蓋率的統計

開發一個Node命令列小玩具全過程--高顏統計工具

安裝&使用

$ npm install -g linec / cnpm install -g linec 
複製程式碼

基礎用法

$ linec
複製程式碼

匯出到html

$ linec -o
複製程式碼

執行完會在當前目錄出現一個output.html

功能

  • 輸出空行,實際行數,總行數
  • 支援400+語言
  • 顯示遍歷速度
  • 顯示多種顏色
  • 支援匯出html

工具原始碼(歡迎star) github.com/hua1995116/…

效果圖

基礎模式

開發一個Node命令列小玩具全過程--高顏統計工具

匯出後開啟html

開發一個Node命令列小玩具全過程--高顏統計工具

結尾

以上就是全部內容,可能對於Node工具開發我可能還是處於初出茅廬的階段,有更規範的操作,歡迎大佬們給我指正。

相關文章