Node.js 快速开发 cli 应用攻略 - 坑篇

「哇夭寿拉,文章都按照上下章来写啦」

因为一直找不到时间写,上次匆匆做完了介绍,所以开个下集谈谈几个库遇到的坑。

commander

commander 的 bug 确实挺多的,所以下一个坑准备试试 yargs 这个库(差点就准备自己写了 OTZ)。

argument 'domain' (and probably others) cause naming collision

本身我们提供了一个 domain 选项进行配置,但是后来发现使用这个选项就会报错……换了个名字就好了。于是翻了一下 issue……看到了一串「保留字」,就是这串保留字让我坚定了下次再也不用的决心:

[ 'Command',
  'Option',
  '__defineGetter__',
  '__defineSetter__',
  '__lookupGetter__',
  '__lookupSetter__',
  '__proto__',
  '_allowUnknownOption',
  '_args',
  '_events',
  '_execs',
  '_maxListeners',
  '_name',
  'action',
  'addImplicitHelpCommand',
  'addListener',
  'alias',
  'allowUnknownOption',
  'apply',
  'args',
  'arguments',
  'bind',
  'call',
  'caller',
  'command',
  'commandHelp',
  'commands',
  'constructor',
  'description',
  'domain',
  'emit',
  'executeSubCommand',
  'hasOwnProperty',
  'help',
  'helpInformation',
  'isPrototypeOf',
  'largestOptionLength',
  'length',
  'listeners',
  'missingArgument',
  'name',
  'normalize',
  'on',
  'once',
  'option',
  'optionFor',
  'optionHelp',
  'optionMissingArgument',
  'options',
  'opts',
  'outputHelp',
  'parse',
  'parseArgs',
  'parseExpectedArgs',
  'parseOptions',
  'propertyIsEnumerable',
  'prototype',
  'rawArgs',
  'removeAllListeners',
  'removeListener',
  'setMaxListeners',
  'toLocaleString',
  'toString',
  'unknownOption',
  'usage',
  'valueOf',
  'variadicArgNotLast',
  'version' ]

如果你要使用保留字就会出现上述错误,并在后头说 3.0 会修复这个问题——然而一年过去了并没有_____

相关 issue: argument 'once' (and probably others) cause naming collision #404

git style commands

在一个「比较大」型的 cli 中,我们可能会想把子命令作为一个「分类」作用,也就是 sub sub command 去决定究竟做什么事情。

如果我们要执行一个添加 token 指令,大致有三种设计:

$ wang token add abcdefg
$ wang token:add abcdefg
$ wang add-token abcdefg

要实现第一种,目前需要使用 Git-style sub-commands,但是实际查了 issue 之后,感觉也有点问题,比如必须要是不带后缀的文件。命名必须是命令-子命令-sub sub command-... 的形式去解析每一层,虽然也可以写 bin 去映射,但是当时觉得和命令名耦合会不会不太好,最终自己实现了一套。

相关 issue: Sub Sub command issues #527

网络库

axios 与 form-data

axios 只有在浏览器环境才提供 form-data 的支持,所以额外使用了一个 form-data 库用于发送请求,当发送布尔值时发生了:

     Uncaught TypeError: first argument must be a string or Buffer
      at ClientRequest.OutgoingMessage.write (_http_outgoing.js:433:11)
      at FormData.ondata (stream.js:51:26)
      at FSReqWrap.oncomplete (fs.js:95:15)

感觉非常哲学,后来发现是因为 Boolean 的锅,必须要是 String 才可以,执行 Boolean 的 toString() 方法手动处理之后就能被正确处理了。

相关 issue: Error when trying to write boolean type #137

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 知识, node.js

已有 2 条评论

  1. 这里是灯塔

    界面好简洁漂亮

  2. 111

    11

添加新评论