写了一个todo list来了解Node js的文件模块
cli.js 入口文件
引入commander 文档
npm install commander
const program = require('commander');
const api = require('./index.js')
program
.option('-x,--xxx','what the x');
//flags description
program
.command('add')
//选项的参数使用方括号声明表示参数是可选参数
.description('add a task')
.action( (...args)=>{
const words = args.slice(0,-1).join(' ')
//使用方括号后,如果输入多个单词只会记录第一个,使用args录入多个单词后最后一位是command命令需要删除
api.add(words).then(()=>{console.log("添加成功")},()=>{console.log("添加失败")})
});
program
.command('clear')
.description('clear all tasks')
.action( ()=>{
api.clear().then(()=>{console.log("清除成功")},()=>{console.log("清除失败")})
})
program.parse(process.argv);
if(process.argv.length === 2){
//说明用户直接运行node cli.js
void api.showAll()
}
index.js 封装相关操作的文件
这里的命令行交互操作使用了inquirer(文档)库来实现的
npm install inquirer
const db = require('./db.js')
const inquirer = require('inquirer')
module.exports.add = async(title) =>{
const list = await db.read()
list.push({title,done:false})
db.write(list)
//读取之前的任务
//添加一个title任务
//存储任务到文件
//面向接口编程
}
module.exports.clear = async(title) =>{
await db.write([])
}
module.exports.showAll = async(title) =>{
const list = await db.read()
list.forEach((task,index)=>{
console.log(`${task.done ?'[x]':'[√]'} ${index+1}-${task.title}`)
})
inquirer
.prompt([
{
type: 'list',
name: 'index',
message: '请选择你想操作的任务',
choices: [
{name:'退出',value:'-1'},
...list.map((task,index)=>{
return {name:`${task.done ? '[√]' : '[x]'} ${index + 1} - ${task.title}`,value:index.toString()}
}),
{name:'+ 创建任务',value:'-2'},
{name:'全部删除',value:'-3'}
],
},
])
.then((answer) => {
const index = parseInt(answer.index)
if(index >= 0 ){
inquirer.prompt({
type:'list',name:'action',
message:'请选择操作',
choices:[
{name:'退出',value:'quit'},
{name:'已完成',value:'markAsDone'},
{name:'未完成',value:'markAsUndone'},
{name:'改标题',value:'updateTitle'},
{name:'删除',value:'remove'},
]
}).then(answer2 =>{
switch(answer2.action){
case 'markAsDone':
list[index].done = true
break;
case 'markAsUndone':
list[index].done = false
break;
case 'updateTitle':
inquirer.prompt(
{
type: 'input',
name: 'title',
message: "新的标题",
default:list[index].title
}
).then((answer) => {
list[index].title = answer.title
db.write(list)
});
break;
case 'remove':
list.splice(index,1)
db.write(list)
break;
}
})
}else if(index === -2 ){
//取名
inquirer.prompt(
{
type: 'input',
name: 'title',
message: "输入新的任务",
}
).then((answer) => {
list.push({
title:answer.title,
done:false,
})
db.write(list)
});
}else if(index === -3){
inquirer.prompt(
{
type: 'input',
name: 'title',
message: "确实要全部删除吗?删除请输入Y,退出输入其他",
}
).then((answer) => {
if(answer.title === 'y'||answer.title === 'Y')
{
list.splice(0)
db.write(list)
console.log("删除成功")
}
});
}
});
}
db.js 文件的读写封装
const fs = require('fs')
const homedir = require('os').homedir()
//系统根目录
const home = process.env.HOME;
//HOME配置目录 一般同上
const p = require('path')
const dbPath = p.join(home,'.todo')
const db = {
read(path = dbPath) {
return new Promise((resolve,reject)=>{
fs.readFile(path,{flag:'a+'},(error,data)=>{
//"a+"如果没有文件则创建
if(error)
{
console.log(error)
reject(error)
}
else {
let list
try{
list = JSON.parse(data.toString())
}
catch(error2){
list = []
}
resolve(list)
}
})
})
},
write(list,path = dbPath) {
return new Promise( (resolve,reject)=>{
const string = JSON.stringify(list)
fs.writeFile(path,string+"\n",(error)=>{
if(error) {return reject(error)}
resolve()
})
})
},
}
module.exports = db
更多详细内容可以看我的github笔记
这里用的commander版本较老3.0.2,换成新版可能有bug