cac 文档翻译 - 图1

cac 文档翻译 - 图2 cac 文档翻译 - 图3 cac 文档翻译 - 图4 cac 文档翻译 - 图5 cac 文档翻译 - 图6 cac 文档翻译 - 图7 cac 文档翻译 - 图8

介绍

CAC 是一个 JavaScript 库,用于构建 CLI 应用。

特征

  • 超轻量级:无依赖,只有一个文件。
  • 易于学习:你需要学习 4 个 API,即可构建简单的 CLI,包括:cli.optioncli.versioncli.helpcli.parse
  • 且如此强大:启用默认命令、类似 git 子命令、验证必填参数和选项、可变参数、点嵌套选项、自动生成帮助消息等功能。
  • 开发人员友好:使用 TypeScript 开发。

目录

  1. yarn add cac

用法

快速上手 - 简单解析

使用 CAC 作为简单的参数解析器:

  1. // examples/basic-usage.js
  2. const cli = require('cac')()
  3. cli.option('--type <type>', 'Choose a project type', {
  4. default: 'node',
  5. })
  6. const parsed = cli.parse()
  7. console.log(JSON.stringify(parsed, null, 2))

cac 文档翻译 - 图9

显示帮助消息和版本号

  1. // examples/help.js
  2. const cli = require('cac')()
  3. cli.option('--type [type]', 'Choose a project type', {
  4. default: 'node',
  5. })
  6. cli.option('--name <name>', 'Provide your name')
  7. cli.command('lint [...files]', 'Lint files').action((files, options) => {
  8. console.log(files, options)
  9. })
  10. // 当使用 `-h` 或 `--help` 参数时显示帮助信息
  11. cli.help()
  12. // 当使用 `-v` 或 `--version` 参数时显示版本号,也可以用于显示帮助信息
  13. cli.version('0.0.0')
  14. cli.parse()

cac 文档翻译 - 图10

命令的特定选项

您可以将选特定项附加到命令中。

  1. const cli = require('cac')()
  2. cli
  3. .command('rm <dir>', 'Remove a dir')
  4. .option('-r, --recursive', 'Remove recursively')
  5. .action((dir, options) => {
  6. console.log('remove ' + dir + (options.recursive ? ' recursively' : ''))
  7. })
  8. cli.help()
  9. cli.parse()

上面配置的选项,会在使用命令时生效。任何位置选项都将视为错误进行提示。但是,如果是基础命令没有定义其行为,则不会验证该选项,如果您真的想使用未知选项,可以使用 [command.allowUnknownOptions](#commandallowunknownoptions)

cac 文档翻译 - 图11

选项名称中的破折号

使用 kebab-case 命名的选项,在使用时需要改为 camelCase 方式:

  1. cli
  2. .command('dev', 'Start dev server')
  3. .option('--clear-screen', 'Clear screen')
  4. .action((options) => {
  5. console.log(options.clearScreen)
  6. })

事实上 --clear-screen--clearScreen 都映射成 options.clearScreen

括号

命令名称中使用括号时,尖括号表示必选参数,而方括号表示可选参数

选项名称中使用括号时,尖括号表示必须传入一个字符串/数字值,而方括号表示该值也可以是true

  1. const cli = require('cac')()
  2. cli
  3. .command('deploy <folder>', 'Deploy a folder to AWS')
  4. .option('--scale [level]', 'Scaling level')
  5. .action((folder, options) => {
  6. // ...
  7. })
  8. cli
  9. .command('build [project]', 'Build a project')
  10. .option('--out <dir>', 'Output directory')
  11. .action((folder, options) => {
  12. // ...
  13. })
  14. cli.parse()

无效选项

如果需要配置选项为 false,您需要手动指定一个无效选项:

  1. cli
  2. .command('build [project]', 'Build a project')
  3. .option('--no-config', 'Disable config file')
  4. .option('--config <path>', 'Use a custom config file')

这将让 CAC 将默认值设置 config 为 true,您可以使用 --no-config 标志将其设置为 false

可变参数

命令的最后一个参数可以是可变参数,并且只能是最后一个参数。要使参数可变,您必须添加 ... 到参数名称的开头,就像 JavaScript 中的 rest 运算符一样。下面是一个例子:

  1. const cli = require('cac')()
  2. cli
  3. .command('build <entry> [...otherFiles]', 'Build your app')
  4. .option('--foo', 'Foo option')
  5. .action((entry, otherFiles, options) => {
  6. console.log(entry)
  7. console.log(otherFiles)
  8. console.log(options)
  9. })
  10. cli.help()
  11. cli.parse()

cac 文档翻译 - 图12

点嵌套选项

点嵌套选项将合并为一个选项。

  1. const cli = require('cac')()
  2. cli
  3. .command('build', 'desc')
  4. .option('--env <env>', 'Set envs')
  5. .example('--env.API_SECRET xxx')
  6. .action((options) => {
  7. console.log(options)
  8. })
  9. cli.help()
  10. cli.parse()

cac 文档翻译 - 图13

默认命令

注册一个将在没有其他命令匹配时使用的命令。

  1. const cli = require('cac')()
  2. cli
  3. // 简单地省略命令名,只使用括号
  4. .command('[...files]', 'Build files')
  5. .option('--minimize', 'Minimize output')
  6. .action((files, options) => {
  7. console.log(files)
  8. console.log(options.minimize)
  9. })
  10. cli.parse()

提供一个数组作为选项值

  1. node cli.js --include project-a
  2. # 解析结果:
  3. # { include: 'project-a' }
  4. node cli.js --include project-a --include project-b
  5. # 解析结果:
  6. # { include: ['project-a', 'project-b'] }

错误处理

全局处理命令错误:

  1. try {
  2. cli.parse(process.argv, { run: false })
  3. // 当你的命令操作返回一个 Promise,你只需要添加 await
  4. await cli.runMatchedCommand()
  5. } catch (error) {
  6. // 在这里处理错误..
  7. // 例如
  8. // console.error(error.stack)
  9. // process.exit(1)
  10. }

使用 TypeScript

首先,您需要 @types/node 在项目中作为开发依赖项安装:

  1. yarn add @types/node --dev

然后一切都开箱即用:

  1. const { cac } = require('cac')
  2. // OR ES modules
  3. import { cac } from 'cac'

使用 Deno

  1. import { cac } from 'https://unpkg.com/cac/mod.ts'
  2. const cli = cac('my-program')

使用 CAC 的项目

这些项目使用了 CAC:

  • VuePress: cac 文档翻译 - 图14 Minimalistic Vue-powered static site generator.
  • SAO: ⚔️ Futuristic scaffolding tool.
  • DocPad: 🏹 Powerful Static Site Generator.
  • Poi: ⚡️ Delightful web development.
  • bili: 🥂 Schweizer Armeemesser for bundling JavaScript libraries.
  • Lad: 👦 Lad scaffolds a Koa webapp and API framework for Node.js.
  • Lass: 💁🏻 Scaffold a modern package boilerplate for Node.js.
  • Foy: 🏗 A lightweight and modern task runner and build tool for general purpose.
  • Vuese: 🤗 One-stop solution for vue component documentation.
  • NUT: 🌰 A framework born for microfrontends
  • Feel free to add yours here…

参考

💁 如果您想要更深入的 API 参考, 请查看源代码中 生成文档

下面简单介绍:

CLI 实例

通过调用 cac 函数创建 CLI 实例:

  1. const cac = require('cac')
  2. const cli = cac()

cac(name?)

创建一个 CLI 实例,可设置可选的 name 属性来指定 CLI 名称,这将用于在帮助和版本消息中显示的 CLI 名称。当未设置时,默认使用 argv[1]

cli.command(name, description, config?)

  • 类型: (name: string, description: string) => Command

创建命令实例。

其第三个参数 config 为可选参数,值为:

  • config.allowUnknownOptions: boolean 在此命令中允许未知选项。
  • config.ignoreOptionDefaultValue: boolean 不要在解析的选项中使用选项的默认值,只在帮助消息中显示它们。

cli.option(name, description, config?)

  • 类型: (name: string, description: string, config?: OptionConfig) => CLI

添加全局选项。

其第三个参数 config 为可选参数,值为:

  • config.default: 选项的默认值。
  • config.type: any[],当设置为 [] 时,选项值返回一个数组类型。还可以使用如 [String] 之类的转换函数,将使用 String 调用选项值。

cli.parse(argv?)

  • 类型: (argv = process.argv) => ParsedArgv
  1. interface ParsedArgv {
  2. args: string[]
  3. options: {
  4. [k: string]: any
  5. }
  6. }

当这个方法被调用时,cli.rawArgscli.argscli.optionscli.matchedCommand 也将可用。

cli.version(version, customFlags?)

  • 类型: (version: string, customFlags = '-v, --version') => CLI

出现标志 -v, --version 时输出版本号。

cli.help(callback?)

  • 类型: (callback?: HelpCallback) => CLI

出现标志 -h, --help 时输出帮助消息。

可选参数 callback 允许在显示之前对帮助文本进行后处理:

  1. type HelpCallback = (sections: HelpSection[]) => void
  2. interface HelpSection {
  3. title?: string
  4. body: string
  5. }

cli.outputHelp()

  • 类型: () => CLI

输出帮助信息。

cli.usage(text)

  • 类型: (text: string) => CLI

添加全局使用说明,并且这不会被子命令使用。

Command 实例

通过调用 cli.command 方法创建 Command 实例:

  1. const command = cli.command('build [...files]', 'Build given files')

command.option()

cli.option 基本相同,但 command.option() 将该选项添加到特定命令中。

command.action(callback)

  • 类型: (callback: ActionCallback) => Command

当命令匹配用户输入时,使用回调函数作为命令操作。

  1. type ActionCallback = (
  2. // Parsed CLI args
  3. // The last arg will be an array if it's a variadic argument
  4. ...args: string | string[] | number | number[]
  5. // Parsed CLI options
  6. options: Options
  7. ) => any
  8. interface Options {
  9. [k: string]: any
  10. }

command.alias(name)

  • 类型: (name: string) => Command

为该命令添加别名,此处 name 不能包含括号。

command.allowUnknownOptions()

  • 类型: () => Command

在此命令中允许未知选项,默认情况下,当使用未知选项时,CAC 将记录错误。

command.example(example)

  • 类型: (example: CommandExample) => Command

在帮助消息末尾显示一个使用示例。

  1. type CommandExample = ((name: string) => string) | string

command.usage(text)

  • 类型: (text: string) => Command

为此命令添加使用说明。

事件

监听命令:

  1. // 监听 `foo` 命令
  2. cli.on('command:foo', () => {
  3. // 执行特定业务
  4. })
  5. // 监听默认命令
  6. cli.on('command:!', () => {
  7. // 执行特定业务
  8. })
  9. // 监听未知命令
  10. cli.on('command:*', () => {
  11. console.error('Invalid command: %s', cli.args.join(' '))
  12. process.exit(1)
  13. })

FAQ

这个名字是如何书写和发音的?

CAC 或 cac,发音为 C-A-C

这个项目是献给我们可爱的 CC sama 的。 也许 CAC 也代表 C&C :P

cac 文档翻译 - 图15

为什么不使用 Commander.js?

Basically I made CAC to fulfill my own needs for building CLI apps like Poi, SAO and all my CLI apps. It’s small, simple but powerful :P

CAC 与 Commander.js 非常相似,而后者不支持点嵌套选项,即类似 --env.API_SECRET foo . 此外,您也不能在 Commander.js 中使用未知选项

也许更多…

基本上,我开发 CAC 是为了满足我自己构建 CLI 应用程序(如 PoiSAO 和我所有的 CLI 应用程序)的需求。

它小巧、简单但功能强大:P

项目统计

cac 文档翻译 - 图16

贡献

  1. Fork 项目!
  2. 创建您的功能分支:git checkout -b my-new-feature
  3. 提交您的更改:git commit -am 'Add some feature'
  4. 推送到分支: git push origin my-new-feature
  5. 提交拉取请求 :D

作者

CAC © EGOIST, Released under the MIT License.

Authored and maintained by egoist with help from contributors (list).

Website · GitHub @egoist · Twitter @_egoistlily