大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Checkpoint: 命令行应用
你将完成什么
用 Node.js 写一个命令行 Todo 应用,包含:添加、列出、完成、删除任务。
验收标准
- 用
process.argv解析命令行参数 - 用
fs模块读写文件(JSON 格式存储) - 用
commander库简化参数解析
核心代码
1. 原生实现
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const FILE = path.join(__dirname, 'todos.json');
// 读取数据
function load() {
if (!fs.existsSync(FILE)) return [];
return JSON.parse(fs.readFileSync(FILE, 'utf-8'));
}
// 保存数据
function save(todos) {
fs.writeFileSync(FILE, JSON.stringify(todos, null, 2));
}
// 解析命令
const [,, command, ...args] = process.argv;
switch (command) {
case 'add':
const todos = load();
todos.push({ id: Date.now(), text: args.join(' '), done: false });
save(todos);
console.log('添加成功');
break;
case 'list':
load().forEach(t => {
console.log(`${t.done ? '[x]' : '[ ]'} ${t.id}: ${t.text}`);
});
break;
case 'done':
const id = parseInt(args[0]);
const updated = load().map(t =>
t.id === id ? { ...t, done: true } : t
);
save(updated);
console.log('完成');
break;
case 'delete':
const deleteId = parseInt(args[0]);
save(load().filter(t => t.id !== deleteId));
console.log('删除成功');
break;
default:
console.log('用法: todo <add|list|done|delete> [args]');
}
# 使用
node todo.js add "买菜"
node todo.js list
node todo.js done 1642000000000
node todo.js delete 1642000000000
2. 用 Commander 库
npm install commander
#!/usr/bin/env node
const { program } = require('commander');
const fs = require('fs');
const path = require('path');
const FILE = path.join(__dirname, 'todos.json');
function load() {
if (!fs.existsSync(FILE)) return [];
return JSON.parse(fs.readFileSync(FILE, 'utf-8'));
}
function save(todos) {
fs.writeFileSync(FILE, JSON.stringify(todos, null, 2));
}
program
.version('1.0.0')
.description('命令行 Todo 应用');
program
.command('add <text...>')
.description('添加任务')
.action((text) => {
const todos = load();
todos.push({ id: Date.now(), text: text.join(' '), done: false });
save(todos);
console.log('添加成功');
});
program
.command('list')
.description('列出所有任务')
.action(() => {
load().forEach(t => {
console.log(`${t.done ? '[x]' : '[ ]'} ${t.id}: ${t.text}`);
});
});
program
.command('done <id>')
.description('完成任务')
.action((id) => {
const updated = load().map(t =>
t.id === parseInt(id) ? { ...t, done: true } : t
);
save(updated);
console.log('完成');
});
program
.command('delete <id>')
.description('删除任务')
.action((id) => {
save(load().filter(t => t.id !== parseInt(id)));
console.log('删除成功');
});
program.parse(process.argv);
# 使用
node todo.js add 买菜
node todo.js list
node todo.js done 1642000000000
node todo.js delete 1642000000000
常见卡点
- 参数解析:
process.argv前两个是node和脚本路径,从第三个开始才是参数。 - JSON 读写:用
JSON.stringify存,JSON.parse取。 - 文件不存在:先检查
fs.existsSync。
加分项
- 用
chalk库加颜色 - 用
inquirer库做交互式选择 - 发布到 npm,全局安装使用
下一步
完成本课后,进入「前端框架」阶段,学习 React。