使用commander和inquirer创建命令行交互项目

1,564 阅读3分钟

最近开始学习node.js

这两天也利用学到的知识做了一个小demo:

使用命令行commander和inquirer库搭配fs文件系统做了一个命令行清单

fs文件系统

利用fs的读操作和写操作,将创建的清单添加到数据里,要想将数据写进文件里,必须要先读数据

readFile读数据

node是异步操作的语言,同样readFile也是异步操作的方法

node内置的fs库里也配置的有同步读数据的方法readFileSync,但是对于此项目我都写的是异步操作

fs.readFile(path,[options],callback)可以写三个参数,也可以写两个参数(【】内的就是可写可不写),第一个参数就是文件的路径,

第二个参数是文件系统标志{flag:' '},控制文件的操作权限,默认是{flag:'r'}只读操作。a+是拥有读写的权限 flag的参数意思

第三个参数是回调函数,当读取失误时就会传入error参数,成功时会传入data,data就是文件读取的内容,但是是二进制的,还需要使用toString()转化为字符串

read(path = dbPath){
    return new Promise((resolve,reject)=>{
        fs.readFile(path,{flag:'a+'},(error,data)=>{
            if(error){return reject(error)}
            let list
            try{
                list = JSON.parse(data.toString())
            } catch(error){
                list = []
            }
            resolve(list)

        })
    })
},

readFile是异步操作,read读方法读文件数据时使用promise

调用此方法的语句加上awitasync

module.exports.add= async (title)=>{
    //读之前的任务 ,因为读取是异步操作所以使用await和async
    const list = await db.read();
}

writeFile写数据

writeFile()要有三个参数,第一个是路径,第二个是要写入的数据(字符串格式),第三个是回调函数

return new Promise((resolve,reject)=>{
    const string = JSON.stringify(list)
    fs.writeFile(path,string,(error)=>{
      if(error){ return reject(error) }
      resolve()
    })
  })

commander.js库

commander.js是node.js命令行的解决方案

安装

首先进行安装

yarn add commander

commander.js的github官方文档

使用

//这两句是引入commander库
const { Command } = require('commander');
const program = new Command();
//这个是自己写的api(读写操作)
const api = require('./index.js')

program
    .option('-x, --xxx', 'what the xxx')
program
//添加指令 add,<taskName>是指令的参数
    .command('add <taskName>')
    .description('add a task')//指令的描述
    .action((title) => {
        //action是操作指令后会干什么
        api.add(title).then(()=>{console.log('添加成功')},()=>{console.log('添加失败')} )
    });
program
    .command('clear')
    .description('clear all task')
    .action(() => {
        api.clear().then(()=>{console.log('清除成功')},()=>{console.log('清除失败')} )
    });

program.parse(process.argv);

options

一个program.option('-x, --xxx', 'what the xxx')就是一个选项文档

使用命令时,node是执行node操作,cli是我的入口文件名,-x就是自己设置的选项

指令

一个完整的program就是一个指令

program
//添加指令 add,<taskName>是指令的参数
    .command('add <taskName>')
    .description('add a task')//指令的描述
    .action((title) => {
        //action是操作指令后会干什么
        api.add(title).then(()=>{console.log('添加成功')},()=>{console.log('添加失败')} )
    });

add就是指令名,<taskName>就是参数名

action就是当你执行这个指令后要干什么

inquirer命令行交互工具

inquirer是命令行交互工具,用户控制选项操作

安装

yarn add inquirer

inquirer的github官方文档

使用

inquirer
  .prompt([
    {
      type:'list',
      name:'index',
      message: '请选择你想要操作的任务?',
     choices: [
         {name:'退出',value:'quit'},
         {name:'已完成',value:'markAsDone'},
        {name:'未完成',value:'markAsUndone'},
        {name:'改标题',value:'updateTitle'},
        {name:'删除',value:'remove'}
     ]
    },
  ])
  .then((answer) => {
      //选中后会执行then操作,answer是选中的项目

  });

发送到npm

在cli入口文件上添加#!/usr/local/bin/node

#!/usr/local/bin/node

让编译器用node执行js代码

修改package配置

{
    //名字必须是小写
  "name": "node-todolist",
  //用t代替cli.js执行命令
  "bin": {
    "t": "cli.js"
  },
  //上传的npm的文件,(所有以js结尾的文件)
  "files": [
    "*.js"
  ],
  "version": "0.0.1",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "commander": "^6.2.1",
    "inquirer": "^7.3.3"
  }
}

在终端执行这一句话,赋予它可执行权限

chmod +x cli.js

在终端登录npm账户

发送之前要把淘宝源修改为npm的官方源 使用 nrm ls 查看源 此时我使用的是淘宝源,切换到npm的官方源

nrm use npm

登录你的npm账户

npm adduser

上传

npm publish