EN

介绍

使用 Func 构建兼顾开发体验、可维护性、运行性能和产物体积的 TypeScript CLI。

更新于

func 是用于构建现代化、可扩展的命令行应用的 TypeScript 框架,它使用类和装饰器声明命令提供:输入和校验,命令分发、错误边界、服务注入以及多种类型安全功能,是从本地开发到生产构建完整流程的高效解决方案。

这不是另一个命令行参数解析包,func 致力于解决命令行应用的架构问题。通过提供完整的项目模型、生态组件、一致的输入运行模型与构建流程等,帮助用户在扩展命令行项目时始终维持项目的生命力与可扩展性。

func 也关注最终包体积与性能,通过自动 Tree Shaking、预编译、解耦组件包等方式尽可能确保你的应用在低体积、高效能的基准上,架构优秀的同时也保持产出也足够精简。无论是原型验证、刚起步的 MVP 还是大型项目,都可以无负担的尝试。

为什么?

命令行项目的复杂度通常上升很快,而且稍加拓展就会难以理解和维护,项目很容易陷入无限的 “打补丁” 与冗余的防守性编程里——一个输入需要同时定义名称、类型、默认值、校验规则和错误提示;不同命令可能需要共享文件读写、网络请求和通用业务规则;发布后还要保证多平台、已有调用方式的兼容性。

如果把这些职责都塞在参数解析和命令回调里,哪怕只是改一个选项,都会同时牵动解析、校验、执行和错误处理逻辑。随着功能增加,每次修改需要梳理和验证的代码范围会越来越大。

CLI 复杂度对可维护性的影响 随着兼容环境、输入输出、字段验证等逻辑加入,可维护性会迅速下降 func 参数解析器
可维护性 容易维护 难维护 1 个命令 多个命令 多个环境 字段验证 参数规则 项目复杂度 → func 参数解析器
func 通过合理的工程组织方式、完善的类型验证、通用校验与规则让维护难度保持平稳;仅依靠参数解析器和本地组织时,命令、规则和依赖越多,维护难度上升得越快。

func 为常见 CLI 功能提供了预制能力,并且要求这些处理器功能都必须严格遵循 TypeScript 类型,这允许工程可承载更多、更复杂的业务模块,你的每次修改只设计核心业务代码,不需要入侵框架,甚至完全不必理解工作原理。

综合考量

体积、冷启动、DX 与可维护性 每个点由 bundle size、冷启动时间和 DX 三个坐标定位;点越大,可维护性代理分越高。
0 25 50 75 100 125 30 40 50 60 70 25 50 75 100 gzip bundle size(KiB) 冷启动(ms) DX func 18.2 KiB · 39.7 ms func/parser 4.5 KiB · 34.7 ms Commander 12.2 KiB · 38.9 ms yargs 34.8 KiB · 71.2 ms @oclif/core 101.9 KiB · 71.4 ms cac 5.1 KiB · 35.1 ms
gzip bundle 与冷启动来自 benchmarks/report.json,三条轴分别采用 0–125 KiB、30–70 ms 和 DX 0–100 的线性刻度。DX 与可维护性来自报告中的 authoring evaluation:每项按 0–4 级评定,再按公开权重折算为 100 分;判定依据和证据随报告提交。这是当前 workload 的工程代理指标,不是通用排名。

在当前基准工作负载中 (benchmarks 为基准的示例项目),func 的平均冷启动时间为 37.9 ms,原始产物为 18.7 KiB:启动性能与 Commander 和 cac 处于同一水准,体积明显小于 yargs 和 oclif,整体处于性能与体积的第一梯队。同一份报告的开发体验和可维护性代理评估中, func 分别得到 95 分和 90 分,均为本次对比中的最高分。

类别 表现 评分
性能 Func 通过反射将所有命令预先注册,保持静态执行,低复杂度
架构设计 提供初始化模板与良好的扩展能力,保持足够的扩展能力
开发者体验 完全类型支持与提示,科学的项目设计与脚手架支持

以下两段代码实现相同的输入规则。func 将类型、默认值和校验放在对应字段上,处理器接收的是已经完成转换和校验的输入。

同一个命令对比

相同的输入规则实现 artifact inspect 命令:必填引用、平台枚举、数字重试次数和 JSON 标志。行数不含 import 与共享业务函数。

Commander 34 行
const artifact = program
  .command('artifact')
  .description('inspect an artifact')

artifact
  .command('inspect')
  .requiredOption('--reference <image>')
  .addOption(
    new Option('--platform <platform>')
      .choices(platforms)
      .default('linux/amd64'),
  )
  .option(
    '--retries <count>',
    'download retries',
    value => {
      const retries = Number(value)
      if (Number.isNaN(retries)) {
        throw new InvalidArgumentError(
          'retries must be a number',
        )
      }
      return retries
    },
    2,
  )
  .option('--json')
  .action(options => {
    if (!isDigestReference(options.reference)) {
      throw new Error(
        'reference must include a sha256 digest',
      )
    }

    inspectArtifact(options.reference, options)
  })
解析回调、默认值和错误分支都堆叠在命令链上。
func 18 行
@Command('artifact')
class ArtifactCommand {
  @Required()
  @ValueValidate(isDigestReference)
  @Value()
  reference?: string

  @Enum(platforms)
  @Value()
  platform: string = 'linux/amd64'

  @Value()
  retries: number = 2

  @Flag()
  json = false

  @Handler('inspect')
  inspect(): void {
    inspectArtifact(this.reference!, this)
  }
}
默认解析器与字段验证器先处理输入;inspect 只调用业务函数。

代码行数不是评价框架的标准。这里仅表明 func 在保持高性能、轻量级的同时,使用更加清晰、现代化、友好的工程方案,使项目始终保持生命力,让人类可以一眼看懂随时可拓展维护。

Agent 适配

除上述之外,func 也有非常优秀的 Agent 适配能力。

func 以类型安全为核心,通过明确严谨的接口固定了命令、输入、校验、处理器和服务之间的边界。这使得 Agent 可以根据项目规则生成安全可靠、稳定合理、符合架构设计的项目代码,如果必要,你甚至可以不参与编写代码,仅提供业务逻辑引导就能完成高质量的终端工具

与此同时,func 还提供了完整的测试支持与 Agent 兼容。Agent 还可以从用户视角运行命令,检查退出行为与稳定输出,添加符合预期的自动化验收测试用例,进一步在自动化中保障业务安全和项目质量。

请打开 Agent 指引 。你可以选择适合当前阶段的任务,让 Agent 创建项目、优化结构或补充 CLI 行为测试。

接下来从哪里开始

按你的当前目标选择文档入口: