【问题标题】:Calling one command in Yargs calls other commands as well在 Yargs 中调用一个命令也会调用其他命令
【发布时间】:2022-11-11 06:55:51
【问题描述】:

我正在学习 nodejs 和 yargs 并尝试使用命令函数在我的代码中实现它。

我正在尝试制作一个基于CLI 的笔记应用程序。

我有两个文件app.jsutils.js,我运行app.jsutils.jsapp.js 中导入以使用其中的函数。

有一个我无法调试的问题,当使用remove 选项调用app.js 时,它也会自动调用add 命令,即使它没有被remove 命令显式调用。

输入:

node app.js remove --title="hello"

输出:

{ _: [ 'remove' ], title: 'hello', '$0': 'app.js' }
Already exists!
Operation successful!

这是我的app.js

// import modules
const validator = require('validator');
const yargs = require('yargs');
// const chalk = require('chalk');
const utils = require('./utils.js');

// version

yargs.version('1.0.0');

const argv = yargs.argv;
console.log(argv);
const command = argv._[0];

// commands
yargs.command({
    command: 'add',
    describe: 'Add a new note',
    builder: {
        overwrite: {
            describe: 'Overwrite the existing file',
            demandOption: true,
            type: 'boolean'
        },
        title: {
            describe: 'Title of the note',
            demandOption: true,
            type: 'string'
        },
        body: {
            body: 'Body of the note',
            demandOption: true,
            type: 'string'
        }
    },
    handler: utils.addNote(argv.overwrite, argv.title, argv.body)
});

yargs.command({
    command: 'remove',
    describe: 'Remove a note by its title',
    builder: {
        title: {
            describe: 'Title to search for',
            demandOption: true,
            type: 'string'
        }
    },
    handler: utils.removeNote(argv.title)
});

// eof
yargs.parse()

这是我的utils.js

// import
const fs = require('fs');

// load notes
function loadNote() {
    try {
        const dataBuffer = fs.readFileSync('notes.json');
        const stringData = dataBuffer.toString();
        const dataJson = JSON.parse(stringData);
        return dataJson;
    } catch (e) {
        return [];
    }
}

// add note
function addNote(overwrite, title, body) {
    const newNote = {
        "title": title,
        "body": body
    };

    const dataJson = loadNote();
    if (overwrite) {
        fs.writeFileSync('notes.json', JSON.stringify([newNote]));
        console.log("Operation successful!");
    } else {
        let flag = true;
        dataJson.forEach(function (object) {
            if (object.title === title) {
                flag = false;
            }
        });
        if (flag) {
            dataJson.push(newNote);
            fs.writeFileSync('notes.json', JSON.stringify(dataJson));
            console.log("Operation successful!");
        } else {
            console.log("Already exists!");
        }
    }
}

// remove notes
function removeNote(title) {
    const dataJson = loadNote();
    dataJson.filter((object) => object.title !== title);
    fs.writeFileSync('notes.json', JSON.stringify(dataJson));
    console.log("Operation successful!");
}

// export
module.exports = {
    addNote: addNote,
    removeNote: removeNote,
};

【问题讨论】:

    标签: javascript node.js npm yargs


    【解决方案1】:

    我在代码中遇到了同样的问题,似乎yargs.commandhandler: 属性需要一个匿名函数作为它的价值。我相信这是因为您的 command 基本上是您函数的“名称”。否则,它被视为常规函数调用。 因此,您需要拥有handler: function(){/*yourFunction()*/}handler: ()=>{/*yourFunction()*/}。我将用我的代码展示一个更详细的示例......

    我的app.js

    const yargs = require('yargs')
    const notes = require('./notes')
    
    
    //set the app.js version
    yargs.version('0.5.0')
    
    //set the notes directory
    const dir = './MyNotes'
    
    /**
     *  Commands
     */
    // Add a note
    yargs.command({
        command: 'add',
        describe: 'Adds a new note',
        builder: {
            'title':{
                describe: 'Note Title',
                demandOption: true,
                type: 'string'
            },
            'body':{
                describe: 'The contents of the note',
                demandOption: true,
                type: 'string'
            }
        },
        handler: (argv)=>{notes.addNote(argv.title,argv.body,dir)}
    })
    
    
    // Remove a note
    yargs.command({
        command: 'remove',
        describe: 'Removes the specified note.',
        builder:{
            title:{
                describe: 'Title of the note you want to remove.',
                type: 'string',
                demandOption: true
            }
        },
        handler:(argv)=>{notes.removeNote(argv.title,dir)}
    })
    
    // Read a note
    yargs.command({
        command: 'read',
        describe: 'Reads the specified note.',
        builder: {
            title:{
                describe: 'The title of the note you want to read.',
                type: 'string',
                demandOption: true
            }
        },
        handler: (argv)=>{notes.readNote(argv.title,dir)}
    })
    
    // List the notes in the directory
    yargs.command({
        command: 'list',
        describe: 'Lists all notes in the directory.',
        handler: ()=>{notes.listNotes(dir)}
    })
    //parse the arguments to execute the commands
    yargs.parse()
    

    我们看最后一条命令“list”;如果您删除 notes.listNotes(dir) 周围的箭头功能...

    yargs.command({
        command: 'list',
        describe: 'Lists all notes in the directory.',
        handler: notes.listNotes(dir)
    })
    

    我将在我的./MyNotes 目录中获得所有笔记的列表每次我运行一个命令(即使它是不同的命令)。

    在重构代码时,请记住 argv 是在运行.在argv创建后,解析并传递给handler:。这意味着您必须将 argv 传递给您的匿名函数您在函数中访问其任何成员。正如我的“读取”命令所见:

    // Read a note
    yargs.command({
        command: 'read',
        describe: 'Reads the specified note.',
        builder: {
            title:{
                describe: 'The title of the note you want to read.',
                type: 'string',
                demandOption: true
            }
        },
        handler: (argv)=>{notes.readNote(argv.title,dir)}
    })
    

    如果我没有将argv 传递给函数, ()=>{notes.readNote(argv.title,dir)} 我会收到错误消息ReferenceError: argv is not defined。我不需要将变量传递给我的list 命令的匿名函数,因为dir 是在编译时间const dir = './MyNotes'

    我希望这有帮助! :D

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多