简介
这是个用于构建cli类型的app的命令行工具库,学习一下维护一个npm库需要做哪些事情
快速上手
// 创建一个cac实例
const cac = new CAC()
// 注册选项,可用尖括号代表必填参数,方括号可选参数
cac.option('--type [type]', 'Choose a project type', {default: 'node'})
// 注册命令,...同展开操作符,可填多个文件
cac.command('lint [...files]', 'lint files').action((files, options) => {
// lint files
})
// 注册命令选项
cac.command('rm <dir>', 'Remove a dir')
.option('-r, --recursive', 'Remove recursively')
.action((dir, options) => {
console.log('remove ' + dir + (options.recursive ? ' recursively' : ''))
})
// 获取命令行输入参数
cac.parse()
实现思路
主要是有CAC、Command、Option三个类,对外提供CAC类。
通过cac类实现command、option的注册
通过面向对象的思想,将option挂在cammand实例上,option收集到cac实例中
用户调用时,通过cac.parse()方法,获取到用户命令行输入,解析得到command name、option和参数,遍历查找comamnd实现对应命令的调用
在调用每个类的方法时,都会返回this,实现连续的api调用,和jquery的方式一致
核心实现说明
Option类
接收三个参数
public rawName: string,
public description: string,
config?: OptionConfig
rawName 定义option 名称,用字符串解析的方式,解析出名称 + 参数,将相关解析结果都记录为自身属性
Command类
实现命令注册,通过输入命令名称 + 参数的字符串模版
在this上存放解析出的各种参数,获得一个command对象后,cac实例会将command对象push收集到自己的coomands数组中
// constructor
this.options = []
this.aliasNames = []
this.name = removeBrackets(rawName) // 解析去掉括号后的参数名、别名
this.args = findAllBrackets(rawName) // 解析出所有的参数,识别参数的特殊形式,如展开参数,
this.examples = []
action
命令对应的行为,command类上带有action的注册方法,传入一个接收了自定义参数和options的回调函数,会在命令执行时执行,同时触发command:${commandName}
事件
Cac类继承了nodejs的EventEmitter类的事件订阅on方法和事件触发emit方法,用户可自行通过
cac.on(() => {})
注册事件
Brackets 的实现
字符串模版解析中,有尖括号和方括号,用来区分可选和必选参数
实际实现中,主要通过以下正则匹配
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g
// 将解析出的参数用以下对象形式描述
{
required: match[0].startsWith('<'),
value,
variadic
}
解析出所有的尖括号和方括号参数后,返回参数数据,存放到command实例上,在parse调用时再做处理
Negated Options 是如何实现的?
解析出对应的点嵌套的option,存到对象中
目录及文件分析
- src存放的是核心代码。通常有一个index文件提供对外导出,utils工具函数,其余的项目核心代码
- examples存放示例代码
- scripts 存放脚本代码
- 根目录下还有一系列的项目配置文件
.editorconfig
- 主流编辑器支持通过此文件定义文件格式,设置文件的换行、缩进
.gitattributes
- 执行git操作时,可以对文件格式进行统一,可以使不同的用户在拉取到代码时有着统一的格式
README
依次由logo、introduction、features、目录、安装方式、使用方式、更详细的API说明、项目相关的荣誉说明(star、引用)、作者信息简介
rollup.config.js
导出了三个配置,分别对应cjs、ts、esm
circle.yml
类似Jenkins的构建工具,支持github