Yargs 经过解析参数和生成高雅的用户界面,用于构建交互式指令行工具。

运用方式

#!/usr/bin/env node
const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const argv = yargs(hideBin(process.argv)).argv
if (argv.ships > 3 && argv.distance < 53.5) {
  console.log('Plunder more riffiwobbles!')
} else {
  console.log('Retreat from the xupptumblers!')
}

hideBin是[process.argv.slice(2)] 的语法糖

摘要

argv

将用户输入的参数转化为目标方式,

yargs(hideBin(process.argv)).argv
yargs(['-a', '-c', '-b', '2']).argv
yargs().parse(['-x', '1', '-y', '2'])
yargs(process.argv.slice(2)).parse()
  • 只会认定 以 – 开头的为参数,只有第一个会被记载进以该参数为键的列表中,后续的会被记载至 argv._ 中;中文也能够被辨认;传入非数字会作为字符串记载进参数目标中;若参数后面没有内容则会记载 true (如下图 -e )
  • $0 记载履行的文件名
  • 只能用于顶级效果域,不能用于函数效果域中
  • 当位于 electron 等环境下,未传入参数名时,运用 hideBin 会疏忽掉第一个参数,这种情况下能够运用.parse(process.argv.slice(1))进行代替

yargs 库不完全指南

array(key)

yargs(hideBin(process.argv)).array('a').argv)

将参数扁平化,因为一次只能扁平化一个参数,能够进行多次链式调用,将一切参数进行扁平化处理

  • 运用 — 能够组织将该参数添加至数组中

yargs 库不完全指南

.command(cmd, desc, [builder], [handler])

.command(cmd, desc, [module])

.command(module)

定义模块向外暴露的指令格式

  • Cmd 是 指令 的字符串或 指令及其别号 的字符串数组。
  • desc 给每个指令提供描绘。将 desc 设置为 false 能够创建躲藏指令。躲藏指令不会显现在帮助输出中,并且无法完结。
  • builder目标 标识指令接受那些参数,标识参数别号、默认值等; builder 也能够是一个函数。第一个参数为 yargs 实例,可对传入的指令进行定制;第二个参数为布尔值 helpOrVersionSet 用来标识是否设置了–help 或 –version。
  • handler 函数 依据最终获取的参数目标 分配履行具体 脚本
yargs
  .command('get', 'make a get HTTP request', {
    url: {
      alias: 'u',
      default: 'http://yargs.js.org/'
    }
  })
  .help()
  .argv

export class BuildCommand implements RspackCommand {
    async apply(cli: RspackCLI): Promise<void> {
        // cli.program 即 yargs
        cli.program.command(
            ["build [entry..]", "$0", "bundle", "b"],
            "run the rspack build",
            yargs =>
                commonOptions(yargs).options({
                    analyze: {
                        type: "boolean",
                        default: false,
                        describe: "analyze"
                    },
                    json: {
                        describe: "emit stats json"
                    }
            }),
            async options => {
                const logger = cli.getLogger();
                let createJsonStringifyStream;
                if (options.json) {
                    const jsonExt = await import("@discoveryjs/json-ext");
                    createJsonStringifyStream = jsonExt.default.stringifyStream;
                }
                const callback = (error, stats: Stats | MultiStats) => {
                    if (error) {
                        logger.error(error);
                        process.exit(2);
                    }
                    if (stats && stats.hasErrors()) {
                        logger.error(stats.toString({ errors: true }));
                        process.exitCode = 1;
                    }
                    if (!compiler || !stats) {
                        return;
                    }
                    const statsOptions = cli.isMultipleCompiler(compiler)
                    ? {
                        children: compiler.compilers.map(compiler =>
                            compiler.options ? compiler.options.stats : undefined)
                    }
                        : compiler.options
                        ? compiler.options.stats
                        : undefined;
                    if (options.json && createJsonStringifyStream) {
                        const handleWriteError = error => {
                            logger.error(error);
                            process.exit(2);
                        };
                    if (options.json === true) {
                        createJsonStringifyStream(stats.toJson(statsOptions as any))
                            .on("error", handleWriteError)
                            .pipe(process.stdout)
                            .on("error", handleWriteError)
                            .on("close", () => process.stdout.write("\n"));
                    } else if (typeof options.json === "string") {
                        createJsonStringifyStream(stats.toJson(statsOptions as any))
                            .on("error", handleWriteError)
                            .pipe(fs.createWriteStream(options.json))
                            .on("error", handleWriteError)
                            // Use stderr to logging
                            .on("close", () => {
                                process.stderr.write(
                                    `[rspack-cli] ${cli.colors.green(
                                    `stats are successfully stored as json to ${options.json}`
                                   )}\n`
                                );
                              });
                            }
                        } else {
                            const printedStats = stats.toString(statsOptions);
                            // Avoid extra empty line when `stats: 'none'`
                            if (printedStats) {
                                logger.raw(printedStats);
                            }
                    }
                };
                let rspackOptions = { ...options, argv: { ...options } };
                const errorHandler = (err, Stats) => {
                    callback(err, Stats);
                };
                const compiler = await cli.createCompiler(
                    rspackOptions,
                    "build",
                    errorHandler
                );
                if (cli.isWatch(compiler)) {
                    return;
                } else {
                    compiler.run(errorHandler);
                }
            }
        );
    }
}

.usage(<message|command>, [desc], [builder], [handler])

用于标识运用哪一条指令

  • 若传递 desc、builder、handler 时,则 usage 的相当于 command 指令

.scriptName($0)

设置履行的脚本名称,默认取指令履行时的文件名(process.argv[1]或 electron app 的process.argv[0])

.middleware(callbacks, [applyBeforeValidation])

注册指令运行时履行的中间件,callback能够传递一个函数,也能够传递函数数组,在指令履行时这些中间件会次序履行

  • 经过将第二个参数设置为true 能够在参数被 验证之前,解析之后 来履行
  • callback 接受两个参数:当前解析的选项目标,yargs实例
  • 修改后的argv目标最终将传递给指令的处理函数。
const mwFunc1 = argv => console.log('I\'m a middleware function');
const mwFunc2 = argv => console.log('I\'m another middleware function');
yargs
  .command('myCommand', 'some command', {}, function(argv){
    console.log('Running myCommand!');
  })
  .middleware([mwFunc1, mwFunc2]).argv;

.parseAsync([args], [context], [parseCallback])

.parseSync([args], [context], [parseCallback])

.parsed [DEPRECATED]

解析参数的三种方式

.positional(key, opt)

.positional() 类似于 .option() ,能够装备指令的方位参数。 .positional()应在指令的构建器函数中调用,在顶级效果域的 yargs 实例上不可用。

const argv = require('yargs/yargs')('run --help')
  .command('run <port> <guid>', 'run the server', (yargs) => {
    yargs.positional('guid', {
      describe: 'a unique identifier for the server',
      type: 'string'
    })
  }).argv
console.log(argv)

yargs 库不完全指南

有用的opt参数列表: positional