yargs高阶用法

28 3月

yargs提供了一些高阶用法

  • Command Module
  • CommandDir
  • 配置文件

Command Module

你可以export/import一个命令,export包含5个部分:command,aliases,describe,builder,handler

// module.js
module.exports.command = 'get <source> [proxy]';
module.exports.describe = 'make a get HTTP request';
module.exports.builder = {
    banana: {
        default: 'cool'
    },
    batman: {
        default: 'sad'
    }
};
module.exports.handler = function (argv) {
    console.log(argv);
};

// advance.js
const yargs = require('yargs');
yargs.command(require('./module.js'))
    .help()
    .argv;
// node advance.js get website pro
// { _: [ 'get' ], banana: 'cool', batman: 'sad', '$0': 'advance.js', source: 'website', proxy: 'pro' }

支持部分export,例如没有export aliases,command,describe 部分:

yargs.command('get <source> [proxy]', 'make a get HTTP request', require('./module'))
  .help()
  .argv;

CommandDir

.commandDir(directory, [opts]):可以将多个命令组织到目录下,一次应用所有命令,而不是多次调用.command(require(‘./dir/module’))。yargs会假定给定目录中的所有模块都是命令模块,如果遇到非命令模块,则会出错(或者用 exclude 或 visit 手动过滤)。默认会忽略子目录。opts:

  • recurse:查找子目录,默认false
  • extensions: 查找的文件类型,默认[‘js’]
  • visit: function型,每个command都会调用该同步方法,参数是 commandObject,pathToFile,filename。返回 commandObject
  • include: RegExp或function型
  • exclude: RegExp或function型

cmds/init.js:

module.exports.command = 'init [dir]';
module.exports.desc = 'Create an empty repo';
module.exports.builder = {
    dir: {
        default: '.'
    }
};
module.exports.handler = function (argv) {
    console.log('init called for dir', argv.dir);
};

cmds/remote.js:

module.exports.command = 'remote <command>';
module.exports.desc = 'Manage set of tracked repos';
module.exports.builder = function (yargs) {
    return yargs.commandDir('remote_cmds');
};
module.exports.handler = function (argv) {};

cmds/remote_cmds/add.js:

module.exports.command = 'add <name> <url>';
module.exports.desc = 'Add remote named <name> for repo at url <url>';
module.exports.builder = {};
module.exports.handler = function (argv) {
    console.log('adding remote %s at url %s', argv.name, argv.url);
};

cmds/remote_cmds/prune.js:

module.exports.command = 'prune <name> [names..]';
module.exports.desc = 'Delete tracked branches gone stale for remotes';
module.exports.builder = {};
module.exports.handler = function (argv) {
    console.log('pruning remotes %s', [].concat(argv.name).concat(argv.names).join(', '));
};

advance.js:

const yargs = require('yargs');
yargs.commandDir('cmds')
    .demandCommand()
    .help()
    .argv;
// node src/yargs/advance.js --help
// node src/yargs/advance.js init               打印出:init called for dir .
// node src/yargs/advance.js remote --help
// node advance.js remote add jack jackurl      打印出:adding remote jack at url jackurl
// node advance.js remote prune jack tim tom    打印出:pruning remotes jack, tim, tom

配置文件

.config([key], [description], [parseFn]) / .config(object):读取配置文件。例如Babel,Eslint都有配置文件,配置文件中的属性会被设为参数:

const findUp = require('find-up');
const fs = require('fs');
const configPath = findUp.sync(['.myapprc', '.myapprc.json']);
const config = configPath ? JSON.parse(fs.readFileSync(configPath)) : {};
const argv = require('yargs')
  .config(config)
  .argv;

// 或者
const argv = require('yargs')
  .config('settings', function (configPath) {
    return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
  })
  .argv;

当然你也可以直接传object:

const argv = require('yargs')
  .config({foo: 1, bar: 2})
  .argv;
console.log(argv);
// node advance.js    打印出:{ _: [], foo: 1, bar: 2, '$0': 'advance.js' }

支持extends参数实现继承:

yargs.config({
  extends: './configs/a.json',
  logLevel: 'verbose'
})

.pkgConf(key, [cwd]):和config()相似,限定从package.json中读取指定的属性,设到参数里:

const argv = require('yargs')
  .pkgConf('dependencies')
  .argv
// node advance.js
// { _: [], yargs: '^13.2.2', 'fs-extra': '^7.0.1', '$0': 'advance.js' }

发表评论

电子邮件地址不会被公开。 必填项已用*标注