MCPcopy
hub / github.com/tj/commander.js

github.com/tj/commander.js @v15.0.0 sqlite

repository ↗ · DeepWiki ↗ · release v15.0.0 ↗
352 symbols 2,041 edges 171 files 156 documented · 44%
README

Commander.js

Build Status NPM Version NPM Downloads Install Size

完整的 node.js 命令行解决方案。

使用其他语言阅读:English | 简体中文

关于本文档中使用的术语,请见术语表

安装

npm install commander

快速开始

编写代码来描述你的命令行界面。 Commander 负责将参数解析为选项和命令参数,为问题显示使用错误,并实现一个有帮助的系统。

Commander 是严格的,并且会针对无法识别的选项显示错误。 两种最常用的选项类型是布尔选项,和从参数中获取值的选项。

示例代码:split.js

const { program } = require('commander');

program
  .option('--first')
  .option('-s, --separator <char>')
  .argument('<string>');

program.parse();

const options = program.opts();
const limit = options.first ? 1 : undefined;
console.log(program.args[0].split(options.separator, limit));
$ node split.js -s - --fits a-b-c
error: unknown option '--fits'
(Did you mean --first?)
$ node split.js -s - --first a-b-c
[ 'a' ]

这是一个使用子命令并带有帮助描述的更完整的程序。在多命令程序中,每个命令(或命令的独立可执行文件)都有一个操作处理程序。

示例代码:string-util.js

const { Command } = require('commander');
const program = new Command();

program
  .name('string-util')
  .description('CLI to some JavaScript string utilities')
  .version('0.8.0');

program.command('split')
  .description('Split a string into substrings and display as an array')
  .argument('<string>', 'string to split')
  .option('--first', 'display just the first substring')
  .option('-s, --separator <char>', 'separator character', ',')
  .action((str, options) => {
    const limit = options.first ? 1 : undefined;
    console.log(str.split(options.separator, limit));
  });

program.parse();
$ node string-util.js help split
Usage: string-util split [options] <string>

Split a string into substrings and display as an array.

Arguments:
  string                  string to split

Options:
  --first                 display just the first substring
  -s, --separator <char>  separator character (default: ",")
  -h, --help              display help for command

$ node string-util.js split --separator=- a-b-c
[ 'a', 'b', 'c' ]

更多示例可以在 examples 目录中找到。

声明 program 变量

为简化使用,Commander 提供了一个全局对象。本文档的示例代码均按此方法使用:

// CommonJS (.cjs)
const { program } = require('commander');

如果程序较为复杂,用户需要以多种方式来使用 Commander,如单元测试等。创建本地 Command 对象是一种更好的方式:

// CommonJS (.cjs)
const { Command } = require('commander');
const program = new Command();
// ECMAScript (.mjs)
import { Command } from 'commander';
const program = new Command();
// TypeScript (.ts)
import { Command } from 'commander';
const program = new Command();

选项

Commander 使用.option()方法来定义选项,同时可以附加选项的简介。每个选项可以定义一个短选项名称(-后面接单个字符)和一个长选项名称(--后面接一个或多个单词),使用逗号、空格或|分隔。

解析后的选项可以通过Command对象上的.opts()方法获取,同时会被传递给命令处理函数。

对于多个单词的长选项,选项名会转为驼峰命名法(camel-case),例如--template-engine选项可通过program.opts().templateEngine获取。

选项及其选项参数可以用空格分隔,也可以组合成同一个参数。选项参数可以直接跟在短选项之后,也可以在长选项后面加上 =

serve -p 80
serve -p80
serve --port 80
serve --port=80

--可以标记选项的结束,后续的参数均不会被命令解释,可以正常使用。

默认情况下,选项在命令行中的顺序不固定,一个选项可以在其他参数之前或之后指定。

.opts()不够用时,还有其他相关方法:

  • .optsWithGlobals()返回合并的本地和全局选项值
  • .getOptionValue().setOptionValue()操作单个选项的值
  • .getOptionValueSource().setOptionValueWithSource()包括选项值的来源

常用选项类型,boolean 型选项和带参数选项

有两种最常用的选项,一类是 boolean 型选项,选项无需配置参数,另一类选项则可以设置参数(使用尖括号声明在该选项后,如--expect <value>)。如果在命令行中不指定具体的选项及参数,则会被定义为undefined

示例代码:options-common.js

program
  .option('-d, --debug', 'output extra debugging')
  .option('-s, --small', 'small pizza size')
  .option('-p, --pizza-type <type>', 'flavour of pizza');

program.parse(process.argv);

const options = program.opts();
if (options.debug) console.log(options);
console.log('pizza details:');
if (options.small) console.log('- small pizza size');
if (options.pizzaType) console.log(`- ${options.pizzaType}`);
$ pizza-options -p
error: option '-p, --pizza-type <type>' argument missing
$ pizza-options -d -s -p vegetarian
{ debug: true, small: true, pizzaType: 'vegetarian' }
pizza details:
- small pizza size
- vegetarian
$ pizza-options --pizza-type=cheese
pizza details:
- cheese

多个布尔短选项可以在破折号之后组合在一起,并且可以跟一个取值的单一选项。 例如 -d -s -p cheese 可以写成 -ds -p cheese 甚至 -dsp cheese

具有预期选项参数的选项是贪婪的,并且无论值如何,都会消耗参数。 所以 --id -xyz 读取 -xyz 作为选项参数。

通过program.parse(arguments)方法处理参数,没有被使用的选项会存放在program.args数组中。该方法的参数是可选的,默认值为process.argv

选项的默认值

选项可以设置一个默认值。

示例代码:options-defaults.js

program
  .option('-c, --cheese <type>', 'add the specified type of cheese', 'blue');

program.parse();

console.log(`cheese: ${program.opts().cheese}`);
$ pizza-options
cheese: blue
$ pizza-options --cheese stilton
cheese: stilton

其他的选项类型,取反选项,以及可选参数的选项

可以定义一个以no-开头的 boolean 型长选项。在命令行中使用该选项时,会将对应选项的值置为false。当只定义了带no-的选项,未定义对应不带no-的选项时,该选项的默认值会被置为true

如果已经定义了--foo,那么再定义--no-foo并不会改变它本来的默认值。

示例代码:options-negatable.js

program
  .option('--no-sauce', 'Remove sauce')
  .option('--cheese <flavour>', 'cheese flavour', 'mozzarella')
  .option('--no-cheese', 'plain with no cheese')
  .parse();

const options = program.opts();
const sauceStr = options.sauce ? 'sauce' : 'no sauce';
const cheeseStr = (options.cheese === false) ? 'no cheese' : `${options.cheese} cheese`;
console.log(`You ordered a pizza with ${sauceStr} and ${cheeseStr}`);
$ pizza-options
You ordered a pizza with sauce and mozzarella cheese
$ pizza-options --sauce
error: unknown option '--sauce'
$ pizza-options --cheese=blue
You ordered a pizza with sauce and blue cheese
$ pizza-options --no-sauce --no-cheese
You ordered a pizza with no sauce and no cheese

选项的参数使用方括号声明表示参数是可选参数(如--optional [value])。该选项在不带参数时可用作 boolean 选项,在带有参数时则从参数中得到值。

示例代码:options-boolean-or-value.js

program
  .option('-c, --cheese [type]', 'Add cheese with optional type');

program.parse(process.argv);

const options = program.opts();
if (options.cheese === undefined) console.log('no cheese');
else if (options.cheese === true) console.log('add cheese');
else console.log(`add cheese type ${options.cheese}`);
$ pizza-options
no cheese
$ pizza-options --cheese
add cheese
$ pizza-options --cheese mozzarella
add cheese type mozzarella

带有可选选项参数的选项不是贪婪的,并且会忽略以破折号开头的参数。因此对于--id -5id表现为布尔选项,但如果需要,您可以使用组合形式,例如 --id=-5

关于可能有歧义的用例,请见可变参数的选项

必填选项

通过.requiredOption()方法可以设置选项为必填。必填选项要么设有默认值,要么必须在命令行中输入,对应的属性字段在解析时必定会有赋值。该方法其余参数与.option()一致。

示例代码:options-required.js

program
  .requiredOption('-c, --cheese <type>', 'pizza must have cheese');

program.parse();
$ pizza
error: required option '-c, --cheese <type>' not specified

变长参数选项

定义选项时,可以通过使用...来设置参数为可变长参数。在命令行中,用户可以输入多个参数,解析后会以数组形式存储在对应属性字段中。在输入下一个选项前(---开头),用户输入的指令均会被视作变长参数。与普通参数一样的是,可以通过--标记当前命令的结束。

示例代码:options-variadic.js

program
  .option('-n, --number <numbers...>', 'specify numbers')
  .option('-l, --letter [letters...]', 'specify letters');

program.parse();

console.log('Options: ', program.opts());
console.log('Remaining arguments: ', program.args);
$ collect -n 1 2 3 --letter a b c
Options:  { number: [ '1', '2', '3' ], letter: [ 'a', 'b', 'c' ] }
Remaining arguments:  []
$ collect --letter=A -n80 operand
Options:  { number: [ '80' ], letter: [ 'A' ] }
Remaining arguments:  [ 'operand' ]
$ collect --letter -n 1 -n 2 3 -- operand
Options:  { number: [ '1', '2', '3' ], letter: true }
Remaining arguments:  [ 'operand' ]

关于可能有歧义的用例,请见可变参数的选项

版本选项

.version()方法可以设置版本,其默认选项为-V--version,设置了版本后,命令行会输出当前的版本号。

program.version('0.0.1');
$ ./examples/pizza -V
0.0.1

版本选项也支持自定义设置选项名称,可以在.version()方法里再传递一些参数(长选项名称、描述信息),用法与.option()方法类似。

program.version('0.0.1', '-v, --vers', 'output the current version');

其他选项配置

大多数情况下,选项均可通过.option()方法添加。但对某些不常见的用例,也可以直接构造Option对象,对选项进行更详尽的配置。

示例代码:options-extra.js, options-env.js, options-conflicts.js, options-implies.js

program
  .addOption(new Option('-s, --secret').hideHelp())
  .addOption(new Option('-t, --timeout <delay>', 'timeout in seconds').default(60, 'one minute'))
  .addOption(new Option('-d, --drink <size>', 'drink size').choices(['small', 'medium', 'large']))
  .addOption(new Option('-p, --port <number>', 'port number').env('PORT'))
  .addOption(new Option('--donate [amount]', 'optional donation in dollars').preset('20').argParser(parseFloat))
  .addOption(new Option('--disable-server', 'disables the server').conflicts('port'))
  .addOption(new Option('--free-drink', 'small drink included free ').implies({ drink: 'small' }));
$ extra --help
Usage: help [options]

Options:
  -t, --timeout <delay>  timeout in seconds (default: one minute)
  -d, --drink <size>     drink cup size (choices: "small", "medium", "large")
  -p, --port <number>    port number (env: PORT)
  --donate [amount]      optional donation in dollars (preset: "20")
  --disable-server       disables the server
  --free-drink           small drink included free
  -h, --help             display help for command

$ extra --drink huge
error: option '-d, --drink <size>' argument 'huge' is invalid. Allowed choices are small, medium, large.

$ PORT=80 extra --donate --free-drink
Options:  { timeout: 60, donate: 20, port: '80', freeDrink: true, drink: 'small' }

$ extra --disable-server --port 8000
error: option '--disable-server' cannot be used with option '-p, --port <number>'

自定义选项处理

选项的参数可以通过自定义函数来处理,该函数接收两个参数,即用户新输入的参数值和当前已有的参数值(即上一次调用自定义处理函数后的返回值),返回新的选项参数值。

自定义函数适用场景包括参数类型转换,参数暂存,或者其他自定义处理的场景。

可以在自定义函数的后面设置选项参数的默认值或初始值(例如参数用列表暂存时需要设置一个初始空列表)。

示例代码:options-custom-processing.js

```js function myParseInt(value, dummyPrevious) { // parseInt 参数为字符串和进制数 const parsedValue = parseInt(value, 10); if (isNaN(parsedValue)) { throw new commander.InvalidArgumentError('Not a number.'); } return parsedValue;

Extension points exported contracts — how you extend this code

ErrorOptions (Interface)
(no doc)
typings/index.d.ts
MyCheeseOption (Interface)
(no doc)
typings/index.test-d.ts
ParseOptions (Interface)
(no doc)
typings/index.d.ts
HelpContext (Interface)
(no doc)
typings/index.d.ts
AddHelpTextContext (Interface)
(no doc)
typings/index.d.ts
OutputConfiguration (Interface)
(no doc)
typings/index.d.ts

Core symbols most depended-on inside this repo

parse
called by 635
lib/command.js
option
called by 426
lib/command.js
command
called by 337
lib/command.js
opts
called by 318
lib/command.js
addOption
called by 191
lib/command.js
action
called by 175
lib/command.js
argument
called by 155
lib/command.js
helpInformation
called by 116
lib/command.js

Shape

Method 219
Function 70
Class 54
Interface 9

Languages

TypeScript100%

Modules by API surface

lib/command.js115 symbols
lib/help.js45 symbols
typings/index.d.ts28 symbols
lib/option.js24 symbols
examples/color-help-replacement.mjs17 symbols
typings/index.test-d.ts11 symbols
lib/argument.js11 symbols
tests/command.createArgument.test.js7 symbols
examples/help-centered.mjs7 symbols
tests/command.createOption.test.js6 symbols
tests/command.createHelp.test.js6 symbols
lib/error.js6 symbols

Dependencies from manifests, versioned

@eslint/js10.0.1 · 1×
@types/node22.7.4 · 1×
eslint10.0.2 · 1×
eslint-config-prettier10.0.1 · 1×
globals17.3.0 · 1×
prettier3.2.5 · 1×
tsd0.33.0 · 1×
typescript6.0.2 · 1×
typescript-eslint8.12.2 · 1×

For agents

$ claude mcp add commander.js \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact