EN

介绍

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

更新于 2周前

func 是一个面向 TypeScript 的轻量 CLI 应用框架。它使用类和装饰器声明命令提供:输入和校验,命令分发、错误边界、服务注入以及多种类型安全功能,是从本地开发到生产构建完整流程的命令行终端项目解决方案。

你可以随时从单命令工具、单文件等小项目起步,随命令和业务规则成长,再按需拆分处理器、服务和模块,全程使用同一套输入模型、运行时和构建流程,始终保持着高效准确的工作方式。因为 func 在确保开发者体验、可维护性、可扩展性的同时,也仍旧保持高性能与低打包体积,无论你的项目在何阶段都适合使用。

为什么需要 func?

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

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

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

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

综合考量

体积、冷启动、DX 与可维护性 每个点由 bundle size、冷启动时间和 DX 三个坐标定位;点越大,可维护性代理分越高。
0 100 200 300 350 35 45 55 65 75 25 50 75 100 bundle size(KiB) 冷启动(ms) DX func 45.0 KiB · 40.1 ms Commander 44.9 KiB · 42.0 ms yargs 115.1 KiB · 71.7 ms @oclif/core 331.3 KiB · 70.8 ms cac 17.0 KiB · 38.8 ms
bundle 与冷启动来自 benchmarks/report.json,三条轴分别采用 0–350 KiB、35–75 ms 和 DX 0–100 的线性刻度。DX 与可维护性来自报告中的 authoring evaluation:每项按 0–4 级评定,再按公开权重折算为 100 分;判定依据和证据随报告提交。这是当前 workload 的工程代理指标,不是通用排名。

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

类别 表现 评分
性能 func 通过反射将所有命令预先注册,保持静态执行,低复杂度
体积 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({ name: 'artifact' })
class ArtifactCommand extends FuncCommand {
  @Required()
  @ValueValidate(isDigestReference)
  @Value()
  reference?: string

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

  @Value({ type: Number })
  retries = 2

  @Flag()
  json = false

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

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

Agent 适配

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

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

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

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

接下来从哪里开始

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