Commander.js是Node.js环境下用于构建命令行工具的核心库,它封装了命令行参数解析、子命令管理、帮助信息生成等通用能力,让开发者无需重复处理底层逻辑,只需关注工具的核心功能实现。无论是简单的单命令工具还是复杂的多命令工具,都可以通过Commander.js快速完成开发。

环境准备与基础安装
首先需要在项目中安装Commander.js,确保本地已经安装了Node.js环境,然后执行以下命令完成依赖安装:
# 初始化项目 npm init -y # 安装commander依赖 npm install commander
基础命令与选项定义
Commander.js的核心是Command对象,所有命令和选项都围绕这个对象进行配置。下面是一个最简单的命令行工具示例,实现查看工具版本的功能:
const { program } = require('commander');
// 定义版本号
program.version('1.0.0');
// 解析传入的命令行参数
program.parse(process.argv);
在终端执行node index.js --version,就会输出定义的版本号1.0.0。接下来可以定义自定义选项,比如添加一个--name选项:
const { program } = require('commander');
program
.option('-n, --name <name>', '输入你的名字')
.action((options) => {
if (options.name) {
console.log(`你好,${options.name}`);
}
});
program.parse(process.argv);
执行node index.js --name 张三,终端会输出你好,张三。这里的<name>表示必填参数,如果使用[name]则表示可选参数。
子命令配置
当工具需要支持多个功能时,可以使用子命令来组织逻辑。比如开发一个文件处理工具,支持read和write两个子命令:
const { program } = require('commander');
// 定义read子命令
program
.command('read <filePath>')
.description('读取指定文件的内容')
.action((filePath) => {
const fs = require('fs');
try {
const content = fs.readFileSync(filePath, 'utf-8');
console.log('文件内容:', content);
} catch (err) {
console.error('读取文件失败:', err.message);
}
});
// 定义write子命令
program
.command('write <filePath> <content>')
.description('向指定文件写入内容')
.action((filePath, content) => {
const fs = require('fs');
try {
fs.writeFileSync(filePath, content);
console.log('写入成功');
} catch (err) {
console.error('写入文件失败:', err.message);
}
});
program.parse(process.argv);
执行node index.js read test.txt就可以读取test.txt的文件内容,执行node index.js write test.txt 测试内容就可以向文件写入内容。
参数校验与自定义帮助信息
Commander.js支持对参数进行校验,也可以自定义帮助信息的展示内容。比如限制--age选项的输入范围:
const { program } = require('commander');
program
.option('-a, --age <number>', '输入年龄', (value) => {
const age = parseInt(value, 10);
if (isNaN(age) || age < 0 || age > 150) {
throw new Error('年龄必须是0到150之间的数字');
}
return age;
});
program.parse(process.argv);
如果输入的年龄不符合要求,工具会自动抛出错误并提示。另外可以通过addHelpText方法添加自定义帮助信息:
const { program } = require('commander');
program
.name('my-tool')
.description('一个自定义的Node.js命令行工具')
.version('1.0.0')
.addHelpText('after', 'n使用示例:n $ my-tool --name 张三n $ my-tool read test.txt');
program.parse(process.argv);
实际开发案例:简易TODO工具
下面是一个完整的TODO管理工具示例,支持添加、查看、删除TODO项:
const { program } = require('commander');
const fs = require('fs');
const path = require('path');
const TODO_FILE = path.join(__dirname, 'todo.json');
// 读取TODO列表
const readTodos = () => {
if (!fs.existsSync(TODO_FILE)) {
return [];
}
const content = fs.readFileSync(TODO_FILE, 'utf-8');
return JSON.parse(content);
};
// 保存TODO列表
const saveTodos = (todos) => {
fs.writeFileSync(TODO_FILE, JSON.stringify(todos, null, 2));
};
program
.name('todo')
.description('简易TODO管理工具')
.version('1.0.0');
// 添加TODO命令
program
.command('add <content>')
.description('添加一个新的TODO项')
.action((content) => {
const todos = readTodos();
todos.push({
id: Date.now(),
content,
done: false
});
saveTodos(todos);
console.log('添加TODO成功');
});
// 查看TODO命令
program
.command('list')
.description('查看所有TODO项')
.option('-d, --done', '只查看已完成的TODO')
.action((options) => {
let todos = readTodos();
if (options.done) {
todos = todos.filter(todo => todo.done);
}
if (todos.length === 0) {
console.log('暂无TODO项');
return;
}
todos.forEach(todo => {
const status = todo.done ? '[已完成]' : '[未完成]';
console.log(`${todo.id} ${status} ${todo.content}`);
});
});
// 删除TODO命令
program
.command('delete <id>')
.description('删除指定ID的TODO项')
.action((id) => {
const todos = readTodos();
const newTodos = todos.filter(todo => todo.id !== Number(id));
if (newTodos.length === todos.length) {
console.log('未找到对应ID的TODO项');
return;
}
saveTodos(newTodos);
console.log('删除TODO成功');
});
program.parse(process.argv);
这个工具会将TODO数据保存在本地的todo.json文件中,执行对应的子命令就可以完成TODO的增删查操作,完整展示了Commander.js在实际项目中的使用方式。
Commander.jsNode.js命令行工具参数解析修改时间:2026-06-29 00:33:40