jerryni / blog

:dog: :dog: :dog:
https://github.com/jerryni/blog/issues
11 stars 4 forks source link

用nodejs写命令行工具 #17

Open jerryni opened 7 years ago

jerryni commented 7 years ago

Table of Contents generated with DocToc

前言

找到合适的工具包,开发nodejs命令行工具是很容易的

准备工作

版本号是我当前使用的版本,可自行选择

Hello World

分4步:

touch index.js创建一个index.js文件,内容如下:

#! /usr/bin/env node

console.log('hello world')

npm init创建一个package.json文件,之后修改成如下:

{
    "name": "npmhelloworld", 
    "bin": {
        "nhw": "index.js" 
    },
    "preferGlobal": true,
    "version": "1.0.0",
    "description": "",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "jerryni <jerryni2014@gmail.com>",
    "license": "ISC"
}

内容详解

index.js

#! /usr/bin/env node

http://stackoverflow.com/questions/33509816/what-exactly-does-usr-bin-env-node-do-at-the-beginning-of-node-files

这句话是一个shebang line实例, 作用是告诉系统运行这个文件的解释器是node; 比如,本来需要这样运行node ./file.js,但是加上了这句后就可以直接./file.js运行了

package.json

{
    // 模块系统的名字,如require('npmhelloworld')
    "name": "npmhelloworld", 
    "bin": {
        "nhw": "index.js" // nhw就是命令名 ,index.js就是入口
    },

    // 加入 安装的时候, 就会有-g的提示了
    "preferGlobal": true,

    // 去掉main: 'xxx.js'  是模块系统的程序入口
    "version": "1.0.0",
    "description": "",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "jerryni <jerryni2014@gmail.com>",
    "license": "ISC"
}

npm link命令

执行后,控制台里面会有以下输出:

/usr/local/bin/nhw -> /usr/local/lib/node_modules/npmhelloworld/index.js
/usr/local/lib/node_modules/npmhelloworld -> /Users/nirizhe/GitHub/npmhelloworld

解释:创建了2个软链接分别放到系统环境变量$PATH目录里,nhw命令和npmhellworld模块。npm link在用户使用的场景下是不需要执行的,用户使用npm i -g npmhellworld命令安装即可。

发布项目到npm官网供大家使用

设置npm用户名,没有的话先到npm官方网站注册一个:

npm set init.author.name "Your Name"
npm set init.author.email "you@example.com"
npm set init.author.url "http://yourblog.com"

npm adduser

项目根目录运行:

npm publish

注意:

每次发布需要修改package.json中的版本号,否则无法发布

如何处理命令行参数

当下比较流程的几个工具对比

这边使用yargs

npm install --save yargs

请看之前我实战一段代码

大概是这个样子:

var argv = yargs
    .option('name', {
        type: 'string',
        describe: '[hostName] Switch host by name',
        alias: 'n'
    })
    .option('list', {
        boolean: true,
        default: false,
        describe: 'Show hostName list',
        alias: 'l'
    })
    .option('close', {
        type: 'string',
        describe: 'close certain host',
        alias: 'c'
    })
    .example('chost -n localhost', 'Switch localhost successfully!')
    .example('chost -c localhost', 'Close localhost successfully!')
    .example('chost -l', 'All host name list: xxx')
    .help('h')
    .alias('h', 'help')
    .epilog('copyright 2017')
    .argv

效果: yargs

单元测试

推荐使用mocha

var assert = require('assert');
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal(-1, [1,2,3].indexOf(4));
    });
  });
});

执行

$ ./node_modules/mocha/bin/mocha

  Array
    #indexOf()
      ✓ should return -1 when the value is not present

  1 passing (9ms)

让你的项目显得正规(github badges)

实际效果就是这些小图标:

badges

这里可以找到各式各样的badges: https://github.com/badges/shields

持续集成(CI)和代码覆盖率

travis Coverage Status

travis-ci:

在travis设置成功后,继续覆盖率的处理:

npm install istanbul coveralls --save-dev

常用的库

shelljs

Portable Unix shell commands for Node.js 在nodejs里用unix命令行

chalk

Terminal string styling done right 给命令行输出上色

参考资料

http://javascriptplayground.com/blog/2015/03/node-command-line-tool/ https://medium.freecodecamp.com/writing-command-line-applications-in-nodejs-2cf8327eee2#.3yg7f98dv http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html https://gist.github.com/coolaj86/1318304

jerryni commented 6 years ago

package.json中的module字段(替换老的main字段),可以告诉新版的nodejs他们的模块都是标准模块,用户可以使用require或import导入。 https://github.com/dherman/defense-of-dot-js/blob/master/proposal.md#typical-usage

jerryni commented 3 years ago

CI地址域名变了:最新的是travis-ci.com 覆盖率工具推荐:codecov