Node.js 中如何收集和解析命令行参数
前言
在开发 cli(command line interface)工具的业务场景下,离不开命令行参数的收集和解析。
接下来,本文介绍如何收集和解析命令行参数。
收集命令行参数
在 node.js 中,可以通过 process.argv 属性收集进程被启动时传入的命令行参数:
由上述示例可以发现,node.js 在处理命令行参数时,只是简单地通过空格来分割字符串。
对于这样的参数数组,无法很方便地获取到每个参数对应的值,所以需要再进行一次解析操作。
命令行参数风格
在解析命令行参数之前,需要了解一些常见的命令行参数风格:
- unix 风格:参数以「-」(连字符)开头
- gnu 风格:参数以「--」(双连字符)开头
- bsd 风格:参数以空格分割
unix 参数风格有一个特殊的注意事项:「「-」后面紧邻的每一个字母都表示一个参数名」。
上述命令用来显示当前目录下所有的文件、文件夹并且显示它们的详细信息,等同于:
gnu 风格的参数以 「--」开头,一般后面会跟上一个单词或者短语,例如熟悉的 npm 安装依赖的命令:
对于两个单词的情况,在 gnu 参数风格中,会通过「-」来连接,例如 npm 安装仅用于开发环境的依赖:
bsd 是加州大学伯克利分校开发的一个 unix 版本。其与 unix 的区别主要在于参数前面没有 「-」,个人感觉这样很难区别参数和参数值。
注意事项:-- 后面紧邻空格时,表示后面的字符串不需要解析。
解析命令行参数
接收到命令行参数数组之后,需要遍历数组,处理每一个参数字符串。
isignorefollowingparameters 方法主要用来判断单个「--」的场景,后续的参数字符串不再需要处理:
接下来,如果参数字符串不以「-」开头,同样也不需要处理,参数的形式以 unix 和 gnu 风格为主:
参数的表现形式主要分为以下几种:
- "--name=xiaoming": 参数名为 name,参数值为 xiaoming
- "-abc=10": 参数名为 a,参数值为 true;参数名为 b,参数值为 true;参数名为 c,参数值为 10
- "--save-dev": 参数名为 save-dev,参数值为 true
- "--age 20":参数名为 age,参数值为 20
利用 unicode 码点值找出连字符和等号的下标值,从而根据下标分割出参数名和参数值:
处理参数值时,需要考虑参数赋值的四种场景:
由于 unix 风格中每一个字母都代表一个参数,并且「手动传递的参数值应该赋值给最后一个参数
」,所以还需针对该场景进行适配:
最后针对参数的赋值操作,需要考虑到「多次赋值」的情况:
到此,命令行参数的解析功能就完成了,上述方法执行的效果如下:
别名机制
比较优秀的 cli 工具在参数的解析上都支持参数的别名设置,例如使用 npm 安装开发环境依赖时,你可以选择这种完整的写法:
你也可以使用下面这种别名方式:
从使用上来说 -d 和 --save-dev 是两种方式,但是从 cli 工具的开发者来说,最终处理逻辑时只能以一个参数名为标准,所以对于一个命令行参数解析库来说,其结果需要包含所有的情况:
以上文的解析方法为例,需要添加额外的选项参数,加入 alias 属性来声明别名属性的对应关系:
上述方式符合正常的理解:设置参数对应的别名。但这是一个「单向查找关系」,需要转化为:
因为对于使用者来说,只会选择一种方式传递参数。对于开发者的话需要根据任意一个别名找到其相关联的别名:
除了别名之外,还可以在参数解析之后做如下优化:
- 参数值的类型约束
- 参数的默认值设定
成熟的解析库
针对一些成熟的命令行参数解析库可以采用基准测试查看它们的解析效率:
本文的内容主要参考解析效率最高的 mri 库的源码,感兴趣的同学可以学习其源码实现。(顺便吐槽一下:嵌套三元操作符可读性真的很差。。)
虽然上述基准测试中 minimist 效率并不很好,但是其覆盖了比较全的参数输入场景。(以上测试用例覆盖的场景有限)
到此这篇关于node.js 中如何收集和解析命令行参数的文章就介绍到这了,更多相关node.js 解析命令行参数内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
上一篇: 在nodejs中创建child process的方法
下一篇: Android 通知栏的使用方法