parseArgs tokens
详细的解析信息可用于通过在配置中指定 tokens: true
添加自定义行为。
返回的令牌具有描述的属性:
- 所有令牌
- 选项令牌
name
<string> 选项的长名称。rawName
<string> 如何在 args 中使用选项,例如--foo
的-f
。value
<string> | <undefined> 参数中指定的选项值。 布尔选项未定义。inlineValue
<boolean> | <undefined> 是否内联指定选项值,如--foo=bar
。
- 位置标记
value
<string> args 中位置参数的值(即args[index]
)。
- 选项终止令牌
返回的令牌按照输入参数中遇到的顺序。
在 args 中出现多次的选项每次使用都会产生一个令牌。
像 -xy
这样的短选项组扩展为每个选项的令牌。
所以 -xxx
产生了三个令牌。
例如,要使用返回的令牌来添加对 --no-color
等否定选项的支持,可以重新处理令牌以更改为否定选项存储的值。
import { parseArgs } from 'node:util';
const options = {
'color': { type: 'boolean' },
'no-color': { type: 'boolean' },
'logfile': { type: 'string' },
'no-logfile': { type: 'boolean' },
};
const { values, tokens } = parseArgs({ options, tokens: true });
// 重新处理选项令牌并覆盖返回值。
tokens
.filter((token) => token.kind === 'option')
.forEach((token) => {
if (token.name.startsWith('no-')) {
// 为 --no-foo 存储 foo:false
const positiveName = token.name.slice(3);
values[positiveName] = false;
delete values[token.name];
} else {
// 如果 --foo 和 --no-foo 都保留值,则最后一个获胜。
values[token.name] = token.value ?? true;
}
});
const color = values.color;
const logfile = values.logfile ?? 'default.log';
console.log({ logfile, color });
const { parseArgs } = require('node:util');
const options = {
'color': { type: 'boolean' },
'no-color': { type: 'boolean' },
'logfile': { type: 'string' },
'no-logfile': { type: 'boolean' },
};
const { values, tokens } = parseArgs({ options, tokens: true });
// 重新处理选项令牌并覆盖返回值。
tokens
.filter((token) => token.kind === 'option')
.forEach((token) => {
if (token.name.startsWith('no-')) {
// 为 --no-foo 存储 foo:false
const positiveName = token.name.slice(3);
values[positiveName] = false;
delete values[token.name];
} else {
// 如果 --foo 和 --no-foo 都保留值,则最后一个获胜。
values[token.name] = token.value ?? true;
}
});
const color = values.color;
const logfile = values.logfile ?? 'default.log';
console.log({ logfile, color });
显示否定选项的示例用法,当一个选项以多种方式使用时,最后一个获胜。
$ node negate.js
{ logfile: 'default.log', color: undefined }
$ node negate.js --no-logfile --no-color
{ logfile: false, color: false }
$ node negate.js --logfile=test.log --color
{ logfile: 'test.log', color: true }
$ node negate.js --no-logfile --logfile=test.log --color --no-color
{ logfile: 'test.log', color: false }
Detailed parse information is available for adding custom behaviours by
specifying tokens: true
in the configuration.
The returned tokens have properties describing:
- all tokens
- option tokens
name
<string> Long name of option.rawName
<string> How option used in args, like-f
of--foo
.value
<string> | <undefined> Option value specified in args. Undefined for boolean options.inlineValue
<boolean> | <undefined> Whether option value specified inline, like--foo=bar
.
- positional tokens
value
<string> The value of the positional argument in args (i.e.args[index]
).
- option-terminator token
The returned tokens are in the order encountered in the input args. Options
that appear more than once in args produce a token for each use. Short option
groups like -xy
expand to a token for each option. So -xxx
produces
three tokens.
For example to use the returned tokens to add support for a negated option
like --no-color
, the tokens can be reprocessed to change the value stored
for the negated option.
import { parseArgs } from 'node:util';
const options = {
'color': { type: 'boolean' },
'no-color': { type: 'boolean' },
'logfile': { type: 'string' },
'no-logfile': { type: 'boolean' },
};
const { values, tokens } = parseArgs({ options, tokens: true });
// Reprocess the option tokens and overwrite the returned values.
tokens
.filter((token) => token.kind === 'option')
.forEach((token) => {
if (token.name.startsWith('no-')) {
// Store foo:false for --no-foo
const positiveName = token.name.slice(3);
values[positiveName] = false;
delete values[token.name];
} else {
// Resave value so last one wins if both --foo and --no-foo.
values[token.name] = token.value ?? true;
}
});
const color = values.color;
const logfile = values.logfile ?? 'default.log';
console.log({ logfile, color });
const { parseArgs } = require('node:util');
const options = {
'color': { type: 'boolean' },
'no-color': { type: 'boolean' },
'logfile': { type: 'string' },
'no-logfile': { type: 'boolean' },
};
const { values, tokens } = parseArgs({ options, tokens: true });
// Reprocess the option tokens and overwrite the returned values.
tokens
.filter((token) => token.kind === 'option')
.forEach((token) => {
if (token.name.startsWith('no-')) {
// Store foo:false for --no-foo
const positiveName = token.name.slice(3);
values[positiveName] = false;
delete values[token.name];
} else {
// Resave value so last one wins if both --foo and --no-foo.
values[token.name] = token.value ?? true;
}
});
const color = values.color;
const logfile = values.logfile ?? 'default.log';
console.log({ logfile, color });
Example usage showing negated options, and when an option is used multiple ways then last one wins.
$ node negate.js
{ logfile: 'default.log', color: undefined }
$ node negate.js --no-logfile --no-color
{ logfile: false, color: false }
$ node negate.js --logfile=test.log --color
{ logfile: 'test.log', color: true }
$ node negate.js --no-logfile --logfile=test.log --color --no-color
{ logfile: 'test.log', color: false }