FUNC - 轻量类型化 CLI 框架

核心概念

一个 func 应用会把装饰过的类注册到 FuncModule 中。运行时,func 会找到匹配用户 CLI 输入的类,选择一个处理器方法,注入字段和参数,然后运行该处理器。

命令作用域

命令作用域是拥有当前 CLI 输入的类。先从两个常见情况开始:没有命令名,以及具名命令。

主命令

@CommandMajor 会在用户不带命令名调用 CLI 时运行。

import { CommandMajor, Handler } from 'func'

@CommandMajor()
export class MajorCommand {
  @Handler()
  run() {
    console.log('welcome')
  }
}

具名命令

当第一个输入 token 匹配 namealias 时,@Command 会运行。

import { Command, Handler } from 'func'

@Command({ name: 'build', alias: 'b' })
export class BuildCommand {
  @Handler()
  run() {
    console.log('build')
  }
}
用户输入 运行 原因
my-cli MajorCommand 没有命令名,因此运行主命令。
my-cli build BuildCommand 第一个输入 token 匹配 build。
my-cli b BuildCommand 第一个输入 token 匹配命令别名。

未知命令

@CommandMissing 是可选的。当你想为无法匹配任何具名命令的输入提供自定义消息时,可以使用它。

import { CommandMissing } from 'func'

@CommandMissing()
export class MissingCommand {
  constructor() {
    console.log('unknown command')
  }
}
用户输入 运行 原因
my-cli unknown MissingCommand 第一个输入 token 不是已注册命令。

处理器

每个命令作用域至少需要一个 @Handler 方法。处理器可以是默认方法、标志触发方法或路径方法。路径处理器会先于标志处理器检查,并且最长匹配路径优先。

import { Command, Handler } from 'func'

@Command({ name: 'config' })
export class ConfigCommand {
  @Handler({ path: ['get'] })
  get() {
    console.log('get config')
  }

  @Handler({ flag: 'help', alias: 'h' })
  help() {
    console.log('usage')
  }

  @Handler()
  run() {
    console.log('config')
  }
}

对于 my-cli config get,会运行路径处理器。对于 my-cli config --help,会运行标志处理器。如果没有路径或标志处理器匹配,则运行默认处理器。

模块与服务

@FuncModule 可以注册命令、导入功能模块并注册服务。服务只会实例化一次,并且可以依赖其他已注册服务。

import { Command, FuncModule, Handler, Service, run } from 'func'

@Service()
class ProjectService {
  name() {
    return 'demo'
  }
}

@Command({ name: 'build' })
class BuildCommand {
  constructor(private project: ProjectService) {}

  @Handler()
  run() {
    console.log(this.project.name())
  }
}

@FuncModule({
  commands: [BuildCommand],
  services: [ProjectService],
})
class AppModule {}

run(AppModule)

后续主题

使用 字段选项 处理标志和值,使用 参数注入 了解 @Args@Regs@Exception,使用 错误处理 了解局部和全局错误处理。