[Series yargs - Bài 3] Middleware Trầm Lặng & Phép Thuật Giao Diện (UI) Trên Terminal
Chào các bạn quay trở lại với chặng cuối của series yargs! Đến lúc này, công cụ CLI của chúng ta đã có thể phân tích cú pháp, ép kiểu dữ liệu và chia file cực kỳ gọn gàng.
Nhưng một công cụ chuyên nghiệp thực sự cần 2 thứ nữa:
- Xử lý ngữ cảnh chung (Context): Ví dụ, trước khi chạy bất kỳ lệnh nào, hệ thống cũng cần kiểm tra xem người dùng đã thiết lập API Token hay chưa. Viết code kiểm tra lặp đi lặp lại ở mọi lệnh là tối kỵ.
- Trải nghiệm người dùng (UX): Một terminal trắng đen nhàm chán sẽ không tạo được ấn tượng. Người dùng cần thấy màu sắc (để phân biệt lỗi và thành công) và các biểu tượng tải (loading spinner) khi công cụ đang gọi API.
Hôm nay, chúng ta sẽ giải quyết cả hai bằng Middleware trong yargs và bộ đôi thư viện chalk, ora.
1. Middleware trong yargs: Người gác đền thầm lặng
Tương tự như khái niệm Middleware trong Express.js, Middleware trong yargs là một hàm sẽ chạy sau khi yargs phân tích xong tham số đầu vào, nhưng trước khi handler của lệnh (command) được thực thi.
Nó đặc biệt hữu ích để:
- Sửa đổi, thêm bớt tham số (ví dụ: tự động chèn thêm ngày giờ hiện tại vào argv).
- Xác thực toàn cục (ví dụ: kiểm tra file config).
Hãy xem cách chúng ta thêm một Middleware vào file app.js:
// file: app.js
const yargs = require('yargs');
const { hideBin } = require('yargs/helpers');
// Hàm Middleware
const checkAuthAndAddTimestamp = (argv) => {
// Giả sử lệnh là 'login' thì không cần kiểm tra token
if (argv._.includes('login')) {
return;
}
// Giả lập việc kiểm tra Token (thực tế có thể đọc từ file hoặc biến môi trường)
const hasToken = process.env.MY_CLI_TOKEN;
if (!hasToken && argv._.length > 0) {
throw new Error('Bạn chưa đăng nhập! Hãy chạy lệnh cấu hình token trước.');
}
// Thêm một tham số ngầm vào argv để các handler dùng
argv.timestamp = new Date().toISOString();
};
yargs(hideBin(process.argv))
.middleware([checkAuthAndAddTimestamp]) // Kích hoạt Middleware
.command({
command: 'profile',
describe: 'Xem thông tin cá nhân',
handler: (argv) => {
// Nhờ middleware, biến argv đã tự động có thêm trường timestamp
console.log(`Lấy dữ liệu lúc: ${argv.timestamp}`);
console.log('Thông tin profile của bạn...');
}
})
.strict()
.help()
.parse();
2. "Lên đồ" cho Terminal với Chalk và Ora
Giờ thì logic đã vững, hãy làm cho CLI của chúng ta "tỏa sáng".
- Chalk: Thư viện giúp đổi màu chữ trên terminal. (Lưu ý: Để tương thích tốt nhất với các project CommonJS (dùng require), hãy cài đặt chalk@4 thay vì bản mới nhất).
- Ora: Thư viện tạo các vòng xoay loading (spinner) cực kỳ chuyên nghiệp.
Cài đặt:
npm install chalk@4 ora@5
Tích hợp vào Command: Hãy viết một lệnh tên là deploy để giả lập quá trình tải mã nguồn lên server.
// file: cmds/deploy.js
const chalk = require('chalk');
const ora = require('ora');
module.exports = {
command: 'deploy',
describe: 'Triển khai mã nguồn lên server',
handler: async (argv) => {
console.log(chalk.blue.bold('\n🚀 Khởi động tiến trình Deploy...\n'));
// Bắt đầu spinner thứ nhất
const spinner = ora('Đang đóng gói mã nguồn (Building)...').start();
// Giả lập thời gian chờ (2 giây)
await new Promise(resolve => setTimeout(resolve, 2000));
// Đổi màu spinner và thông báo thành công
spinner.succeed(chalk.green('Đóng gói thành công!'));
// Chuyển sang bước 2
spinner.start('Đang tải lên server...');
await new Promise(resolve => setTimeout(resolve, 3000));
// Giả lập lỗi ngẫu nhiên
const isError = Math.random() > 0.7;
if (isError) {
spinner.fail(chalk.red.bold('Lỗi mạng! Không thể kết nối tới server.'));
process.exit(1);
} else {
spinner.succeed(chalk.green('Tải lên hoàn tất!'));
console.log(chalk.bgGreen.black('\n 🎉 DEPLOY SUCCESSFUL! 🎉 \n'));
}
}
};
Chạy thử lệnh:
node app.js deploy
Lúc này, thay vì những dòng text tĩnh khô khan, bạn sẽ thấy màu sắc rực rỡ và vòng xoay loading vô cùng sinh động, giống hệt trải nghiệm khi bạn dùng Vercel CLI hay Heroku CLI.
Tổng kết Series yargs
Chỉ với 3 bài viết, bạn đã đi từ một người mới làm quen với dòng lệnh process.argv trở thành một nhà phát triển có khả năng xây dựng các CLI tool phức tạp. Chúng ta đã học được:
- Cách khởi tạo CLI tự động sinh Document (--help) với yargs.
- Phân chia kiến trúc mã nguồn sạch sẽ bằng commandDir và validation.
- Chặn bắt request bằng Middleware và làm đẹp giao diện với Chalk + Ora.
Những công cụ CLI tự viết này sẽ giúp bạn tự động hóa rất nhiều quy trình nhàm chán trong công việc hàng ngày (như tự động clone template project, sinh file boilerplate, hay viết tool deploy nội bộ).
Cảm ơn các bạn đã đồng hành cùng series này. Chúc các bạn code vui vẻ và tạo ra được những công cụ thật ngầu!
All Rights Reserved