minimist : command line parser of node.js

655 查看

minimist 是一个node 模块,用来做命令行参数解析。

比如,解析

 $ls -a avalue -b bvalue arg 

效果简练,功能俊秀:

  var d  ="ls -a avalue -b bvalue arg".split(' ')
  var opt = require('minimist')
  var argv = opt(d);
  expect(argv.a).to.equal("avalue")
  expect(argv.b).to.equal("bvalue")      
  expect(argv._).to.deep.equal("ls arg".split(' '))

这里的-a,-b 都是一个string类型的参数,值分别为 avalue,bvalue 。具体的命令格式和参数类型,需要自己去看看此模块的readme。

对于 $ls -ar " 的解析,也还得体:

        var d  ="ls -ar c".split(' ')
        var argv = opt(d);
        expect(argv.a).to.equal(true)
        expect(argv.r).to.equal(true)   

这里的-a,-r都是boolean类型的,有就是true,没有就是false。

可是,如果是 $ls -ar r

  var d  ="ls -ar r".split(' ')
  var opt = require('minimist')
  var argv = opt(d);
  expect(argv.a).to.equal(true)
  expect(argv.r).to.equal("r")
  expect(argv._).to.deep.equal("ls".split(' '))

有些歧义出现。-a 自然无话可说,就是一个boolean参数。-r呢,到底是Boolean参数,还是一个值为r的string参数呢?

解决此问题也还简单。为了消除歧义,指定r为boolean类型即可。

  var d  ="ls -ar r".split(' ')
  var opt = require('minimist')
  var argv = opt(d);
  var argv = opt(d,{boolean:["r"]});
  console.log(argv)
  expect(argv.a).to.equal(true)
  expect(argv.r).to.equal(true)
  expect(argv._).to.deep.equal("ls r".split(' '))

----------------干净的表象,自此堕入黑暗 -------------

我想要做一个cross shell,跨平台运行shell,在mac,windows上。作为此工作的一个sub project,我需要用到option parser。

有两个选项:minimist ,optimist 。optimist是我先知道的,但是此组件的作者自己用 minimist !他还说明了原因:

   DEPRECATION NOTICE:I don't want to maintain this module anymore 
   since I just use minimist, the argument parsing engine, 
   directly instead nowadays.

于是我npm i minimist 。

回到本意,我要解析ls命令的简版,以便适配 shell.js 。语料为:

  ls -fg c

结果是:

 {
      _: [ 'ls', 'b' ],
      f: true,
      g: 'c',
  }

怎么办?原来必须指定fg为boolean。不说明的话,默认的行为虽然不是我现在希望的,但是它这样做也有特定的场景的

   ls -o1 o1value -o2 o2value value

所以指定即可

  var d  ="ls b -fg c".split(' ')
  var opt = require('minimist')
  var argv = opt(d,{boolean:["f","g"]});
  expect("f" in argv).to.equal(true)
  expect("g" in argv).to.equal(true)
  expect(argv._).to.deep.equal("ls b c".split(' '))

花了不少时间去修改了minimist 以便完成我的需求,完成代码后才发现还可以这样做 。果然还是需要细读文档;比读文档更重要的,是需要对unix command line的格式约定烂熟于心。这次的坑就在于我不那么清楚这个逻辑。