Node.js 快速开发 cli 应用攻略 - 坑篇
「哇夭寿拉,文章都按照上下章来写啦」
因为一直找不到时间写,上次匆匆做完了介绍,所以开个下集谈谈几个库遇到的坑。
commander
commander 的 bug 确实挺多的,所以下一个坑准备试试 yargs
这个库(差点就准备自己写了 OTZ)。
argument 'domain' (and probably others) cause naming collision
本身我们提供了一个 domain
选项进行配置,但是后来发现使用这个选项就会报错……换了个名字就好了。于是翻了一下 issue……看到了一串「保留字」,就是这串保留字让我坚定了下次再也不用的决心:
1[ 'Command',
2 'Option',
3 '__defineGetter__',
4 '__defineSetter__',
5 '__lookupGetter__',
6 '__lookupSetter__',
7 '__proto__',
8 '_allowUnknownOption',
9 '_args',
10 '_events',
11 '_execs',
12 '_maxListeners',
13 '_name',
14 'action',
15 'addImplicitHelpCommand',
16 'addListener',
17 'alias',
18 'allowUnknownOption',
19 'apply',
20 'args',
21 'arguments',
22 'bind',
23 'call',
24 'caller',
25 'command',
26 'commandHelp',
27 'commands',
28 'constructor',
29 'description',
30 'domain',
31 'emit',
32 'executeSubCommand',
33 'hasOwnProperty',
34 'help',
35 'helpInformation',
36 'isPrototypeOf',
37 'largestOptionLength',
38 'length',
39 'listeners',
40 'missingArgument',
41 'name',
42 'normalize',
43 'on',
44 'once',
45 'option',
46 'optionFor',
47 'optionHelp',
48 'optionMissingArgument',
49 'options',
50 'opts',
51 'outputHelp',
52 'parse',
53 'parseArgs',
54 'parseExpectedArgs',
55 'parseOptions',
56 'propertyIsEnumerable',
57 'prototype',
58 'rawArgs',
59 'removeAllListeners',
60 'removeListener',
61 'setMaxListeners',
62 'toLocaleString',
63 'toString',
64 'unknownOption',
65 'usage',
66 'valueOf',
67 'variadicArgNotLast',
68 'version' ]
69
如果你要使用保留字就会出现上述错误,并在后头说 3.0 会修复这个问题——然而一年过去了并没有_____
相关 issue: argument 'once' (and probably others) cause naming collision #404
git style commands
在一个「比较大」型的 cli 中,我们可能会想把子命令作为一个「分类」作用,也就是 sub sub command
去决定究竟做什么事情。
如果我们要执行一个添加 token
指令,大致有三种设计:
1$ wang token add abcdefg
2$ wang token:add abcdefg
3$ wang add-token abcdefg
4
要实现第一种,目前需要使用 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()
方法手动处理之后就能被正确处理了。
评论 (2)
11
界面好简洁漂亮