npm 在Yargs中调用一个命令也会调用其他命令

k2fxgqgv  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(130)

我正在学习nodejs和yargs,并试图在我的代码中使用命令函数实现它。
我正在尝试做一个基于CLI的笔记应用程序。
我有两个文件app.jsutils.js,我运行app.jsutils.js是导入到app.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()

这是我的第一张专辑

// 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,
};
juzqafwq

juzqafwq1#

我在我的代码中遇到了同样的问题,yargs.commandhandler:属性需要一个 Anonymous Function 作为它的值。我相信这是因为你的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”命令所示:

// 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

相关问题