Contents

Cách xây dựng ứng dụng CLI trong Node.js

Ứng dụng CLI (Giao diện dòng lệnh) là các ứng dụng dựa trên văn bản đơn giản chạy trong thiết bị đầu cuối để hoàn thành các tác vụ cụ thể. Các ứng dụng CLI đóng một vai trò quan trọng trong quy trình làm việc của hầu hết mọi nhà phát triển và chuyên gia CNTT.

Hầu hết các chương trình phần mềm này đóng vai trò là tiện ích, tương tác với hệ điều hành hoặc ứng dụng, cho dù nó được cài đặt trên thiết bị cục bộ hay được truy cập qua internet, để thực hiện các tác vụ dựa trên lệnh và hướng dẫn của người dùng.

Tìm hiểu ứng dụng CLI

Giao diện dòng lệnh tạo điều kiện tương tác giữa người dùng và chương trình thông qua việc nhập các lệnh văn bản. Hoạt động của nhiều ứng dụng CLI có thể khác nhau đáng kể tùy theo lệnh khởi tạo được sử dụng.

Thật vậy, lệnh “ls” được sử dụng để hiển thị chi tiết về tệp và thư mục ở định dạng thân thiện với người dùng. Người ta có thể thực thi nó bằng cách nhập lệnh theo sau là bất kỳ tham số hoặc tùy chọn mong muốn nào.

 ls -l /home 

Lệnh này bao gồm:

Tiện ích dòng lệnh được gọi là “ls” được sử dụng để liệt kê và quản lý các tệp trong một thư mục trong hệ điều hành Linux hoặc Unix. Nó cung cấp cho người dùng thông tin về quyền, quyền sở hữu, kích thước, ngày sửa đổi và các chi tiết liên quan khác liên quan đến tệp được lưu trữ trên hệ thống của họ.

Cờ nói trên, được biểu thị bằng’-l’, đóng vai trò thay thế cho thuật ngữ"dài", gợi ra mức độ cụ thể cao hơn trong đầu ra của nó.

Trong ngữ cảnh này, “Đối số” đề cập đến một tham số hoặc phần dữ liệu được sử dụng trong một chương trình hoặc hệ thống để chỉ định một vị trí hoặc thư mục cụ thể mà từ đó thông tin sẽ được truy xuất hoặc hiển thị. Đoạn mã đã cho cho biết rằng đường dẫn đã chỉ định có thể được truy cập và xử lý bởi tập lệnh hoặc ứng dụng hiện có.

Khi phát triển giao diện dòng lệnh cho một ứng dụng phần mềm, điều quan trọng là phải tuân thủ các quy ước đã thiết lập để đảm bảo khả năng sử dụng và khả năng truy cập cho người dùng đã quen làm việc trong loại môi trường này. Bằng cách kết hợp các yếu tố thường được sử dụng, bạn có thể tăng khả năng những người dùng chưa quen với chương trình cụ thể của bạn vẫn có thể điều hướng và tương tác với chương trình đó một cách hiệu quả.

Commander.js là gì?

Commander.js là gói npm hỗ trợ phát triển các ứng dụng giao diện dòng lệnh (CLI) bằng Node.js. Gói này cung cấp một bộ công cụ và chức năng toàn diện cho phép các nhà phát triển tạo ra các ứng dụng CLI mạnh mẽ mà không tốn nhiều công sức. Với Commander.js, các nhà phát triển có thể chỉ định các lệnh, tùy chọn và hành vi mà ứng dụng CLI của họ yêu cầu mà không phải lo lắng về các chi tiết triển khai cơ bản.

Bằng cách tích hợp Chalk.js cùng với gói này, người ta có thể dễ dàng tạo ra một ứng dụng giao diện dòng lệnh hoạt động toàn diện trong môi trường Node.js.

Xây dựng ứng dụng CLI trong Node.js bằng Commander.js

Hãy xem xét một ví dụ về ứng dụng CLI, urbanary-cli, ứng dụng này tra cứu ý nghĩa của các từ và từ viết tắt trên mạng xã hội từ Từ điển đô thị. Bạn sẽ tìm hiểu cách tạo CLI và xuất bản nó lên sổ đăng ký gói npm để những người khác có thể cài đặt nó.

Vui lòng làm theo các bước sau để tạo thư mục mới và khởi tạo dự án Node.js mới bằng giao diện dòng lệnh:1. Mở terminal hoặc dấu nhắc lệnh trên máy tính của bạn.2. Điều hướng đến vị trí mong muốn nơi bạn muốn tạo thư mục mới bằng cách nhập đường dẫn thư mục thích hợp. Ví dụ: nếu bạn muốn tạo một thư mục mới có tên “my-project” trong thư mục chính của mình, hãy nhập lệnh sau: cd ~/my-project.3. Khi bạn đã điều hướng đến đúng thư mục, hãy sử dụng lệnh mkdir theo sau là tên của thư mục bạn muốn tạo. Trong trường hợp này, lệnh sẽ là mkdir my-project. Thao tác này sẽ tạo một thư mục trống mới có tên “my-project”.4. Sau khi tạo thư mục mới, điều hướng trở lại

 mkdir urbanary-cli
cd urbanary-cli
npm init -y

CLI này sẽ sử dụng Axios để gửi yêu cầu HTTP tới API Từ điển đô thị. Bạn có thể sử dụng API nhanh để kiểm tra điểm cuối và xem thông tin xác thực.

/vi/images/urban_dict_rapid_api_page.jpg

CLI đơn giản với lệnh phụ và trợ giúp

Để bắt đầu xây dựng Giao diện dòng lệnh (CLI), bạn sẽ cần cài đặt hai thành phần thiết yếu-“Commander” và “Axios”. Bạn có thể làm như vậy bằng cách thực thi một lệnh duy nhất kết hợp cả hai phần phụ thuộc trong quá trình cài đặt của nó. Lệnh cần thiết như sau:

 npm install commander axios

Vui lòng tạo một thư mục mới có tên “bin” trong thư mục dự án của bạn cũng như một tệp trống có tiêu đề “index.js”.

 mkdir bin
cd bin
touch index.js

Thư mục “bin”, viết tắt của “binary”, có tầm quan trọng đáng kể vì nó chứa tệp điểm vào mà NodeJS gọi khi chạy ứng dụng giao diện dòng lệnh (CLI). Tệp điểm nhập này được gọi là tệp “index.js”. Để bắt đầu xây dựng CLI của riêng bạn bằng thư viện Commander.js, vui lòng sửa đổi tệp “index.js” đã nói ở trên.

Đầu tiên, nhập đối tượng chương trình từ Commander:

 const { program } = require('commander');

Sử dụng đối tượng chương trình làm công cụ để mô tả giao diện ứng dụng của bạn, bao gồm các lệnh, lựa chọn và tham số phụ. Thực thể này có các thủ tục đối ứng tương ứng với từng khía cạnh tương ứng; Đáng chú ý là, để thiết lập quyền chỉ huy cấp dưới, hãy sử dụng

Chắc chắn, đây là ví dụ về cách bạn có thể xác định lệnh phụ find trong tập lệnh CLI sử dụng gói urbandictionary-api để tìm kiếm các từ trên Urban Từ điển và hiển thị định nghĩa của chúng:javascriptconst { nhắc }=require(’https://www.npmjs.com/package/prompt’);const UrbanDictionaryAPI=require(’./urban-dictionary-api’).default;//Hàm lấy định nghĩa của từ bằng cách tìm kiếm trong từ điển đô thị apiasync function find(word) {const result=wait UrbanDictionaryAPI.getDefDef({ query: word });console.log( ${word}-${result} );}module.exports={ find };Mã này định nghĩa một hàm find nhận một đối số duy nhất

 // index.js
program
    .command('find <word>')
    .description('find meaning of a word or abbreviation or slang')

Đoạn mã được cung cấp minh họa cách triển khai hàm find trong JavaScript, sử dụng dấu ngoặc nhọn ( <> ) trong dấu ngoặc kép "" để xác định một tham số có yêu cầu bắt buộc. Ngoài ra, dấu ngoặc vuông [] có thể được sử dụng nếu sự hiện diện của tham số là tùy chọn.

Việc kết hợp một tài khoản minh họa rất được khuyến khích vì Commander.js sử dụng thông tin này để tạo ra nội dung thông tin nhằm mục đích hỗ trợ. Khi được thực thi thông qua lệnh’trợ giúp’, hướng dẫn sử dụng thông thường sẽ được trình bày.

Để kiểm tra điều này, hãy thêm vào như sau:

 program.parse() 

Sau khi thực hiện chương trình và cung cấp lệnh “trợ giúp”, kết quả tiếp theo như sau:

/vi/images/help_command_output.jpg

Việc sử dụng phương pháp thông thường để trình bày hỗ trợ trong ứng dụng Giao diện dòng lệnh (CLI) tiêu chuẩn là một phương pháp phổ biến mà không cần nỗ lực thêm từ các nhà phát triển khi triển khai thư viện Commander. Người dùng có thể dễ dàng truy cập hướng dẫn được cung cấp bằng cách nhập tùy chọn “-h” hoặc “–help” theo sau là lệnh mong muốn của họ để xem lại hướng dẫn sử dụng được liên kết với từng lệnh riêng lẻ.

Xác định các lựa chọn và chuẩn bị chương trình cuối cùng

Bạn có thể điều chỉnh thêm hành vi của lệnh bằng cách sử dụng phương thức tùy chọn kết hợp với định nghĩa lệnh, liên kết chúng với nhau một cách hiệu quả thông qua kỹ thuật này được gọi là “chuỗi”.

Để kết hợp các ví dụ minh họa trong phần giải thích bằng lời của từ vựng, người ta có thể làm theo quy trình sau:

 program.option('-e,--example', "Display examples")

Đây là một cách để chỉ định một tùy chọn xác định số lượng định nghĩa được trả về:

 program.option(
    '-c,--count [amount]',
    'amount of definitions to display (max is 10)'
)

Phương pháp tạo điều kiện thuận lợi cho việc lựa chọn từ một loạt các lựa chọn thay thế sử dụng hai chuỗi làm đầu vào, trong đó một chuỗi đại diện cho chỉ định của lựa chọn ở cả định dạng ngắn gọn và mở rộng, trong khi chuỗi thứ hai tóm tắt phần trình bày đi kèm của nó. Ngoài ra, một tham số tùy chọn được biểu thị bằng “số lượng” chỉ định chữ số tương ứng với số lượng bản tóm tắt cần thiết sẽ được hiển thị.

Phương thức cuối cùng cần kết hợp trong quá trình triển khai của chúng tôi là phương thức action , dùng để thực thi các thao tác vốn có của lệnh find. Bằng cách đưa phương thức này vào cơ sở mã, chúng tôi có thể đảm bảo rằng chương trình của chúng tôi tuân thủ cấu trúc giống với mẫu được cung cấp. Do đó, cấu hình kết quả của mã của chúng tôi sẽ có định dạng tương tự như sau:

 program
    .command('find <word>')
    .description('find meaning of a word or abbreviation or slang')
    .option('-e,--example', "Display examples")
    .option(
        '-c,--count [amount]',
        'amount of definitions to display (max is 10)'
    )
    .action(async (word, options) => {});

Bằng cách kết hợp cấu hình được cung cấp, việc thực hiện yêu cầu cho ba trường hợp “haha” cùng với các hình minh họa tương ứng có thể giống như sau:

 urbanary-cli find lol -e -c 3

Một cách tiếp cận khác để giải quyết vấn đề này có thể là khám phá một quan điểm hoặc chiến lược khác để xử lý nó. Một khả năng là xem xét các lựa chọn sẵn có khác có thể mang lại kết quả thuận lợi hơn những lựa chọn hiện đang được theo đuổi. Điều này có thể liên quan đến việc tìm kiếm thông tin bổ sung về các giải pháp tiềm năng hoặc tham khảo ý kiến ​​của các chuyên gia trong các lĩnh vực liên quan, những người có thể đưa ra những hiểu biết và đề xuất có giá trị. Bằng cách thực hiện những bước như vậy, chúng ta có thể cố gắng đạt được kết quả tốt hơn đồng thời tránh được những hậu quả tiêu cực liên quan đến đường lối hành động hiện tại của mình.

 urbanary-cli find lol --example --count 3

Hãy xem trang npm của Commander để tìm hiểu thêm về nó và cách điều chỉnh các chức năng của nó cho phù hợp với các trường hợp sử dụng khác nhau của bạn.

Triển khai chức năng của chương trình

Kết hợp thư viện Axios vào tệp index.js bằng cách thực hiện các bước sau:

 const axios = require('axios');

Trong các tham số chức năng của phương thức của đối tượng “hành động”, người ta có thể kết hợp mã cần thiết để tương tác với Từ điển đô thị và trình bày kết quả dựa trên các ưu tiên được xác định trước.

Bắt đầu bằng cách xác định yêu cầu của bạn:

 let requestOptions = {
    method: 'GET',
    URL: "https://mashape-community-urban-dictionary.p.rapidapi.com/define",
    params: { term: word },
    headers: {
        'X-RapidAPI-Key': YOUR_RAPID_API_KEY,
        'X-RapidAPI-Host': 'mashape-community-urban-dictionary.p.rapidapi.com'
    }
}

Để truy cập API bằng Axios, người ta có thể sử dụng dòng mã sau:javascriptaxios.get(’https://api.example.com/data’).then(response=>//xử lý dữ liệu phản hồi tại đây}).catch(error=> {//xử lý lỗi tại đây});

 try {
    let resp = await axios.request(requestOptions);
    console.log(`Definitions for ${word} fetched`);
    wordData = resp.data.list;
} catch (err) {
    console.error(err.message)
}

Một trong những thông tin quan trọng mà chúng tôi yêu cầu từ dữ liệu phản hồi là thuộc tính có thể đếm được, chứa tập hợp các định nghĩa và hình minh họa.

Kết hợp đoạn mã sau vào khối thử hiện có, đảm bảo rằng nó xử lý đầu vào tùy chọn và hiển thị đầu ra tương ứng tương ứng:

 if (options.example && options.count) {
    let cnt = 1;
    let definitions = wordData.slice(0, options.count);

    definitions.forEach((elem) => {
        console.log(`Definition ${cnt\+\+}: ${elem.definition}`);
        console.log(`Example:\n${elem.example}\n`);
    });
} else if (options.count && !options.example) {
    let cnt = 1;
    let definitions = wordData.slice(0, options.count);

    definitions.forEach((elem) => {
        console.log(`Definition ${cnt\+\+}: ${elem.definition}`);
    });
} else if (options.example) {
    console.log(`Definition: ${wordData[0].definition}`);
    console.log(`Example:\n${wordData[0].example}`);
} else {
    console.log(`Definition: ${wordData[0].definition}`);
}

Mã hiện tại phân tích các lệnh đầu vào bằng cách sử dụng các câu lệnh có điều kiện để xác định phương pháp thích hợp nhất để hiển thị kết quả. Trong trường hợp các tham số bao gồm một phiên bản minh họa, một ký tự phân cách và tùy chọn kiểm đếm được cung cấp, chương trình sẽ lặp lại dữ liệu liên quan đến từng từ riêng lẻ và in ra số lượng định nghĩa và phiên bản mẫu cần thiết tương ứng.

Hàm sẽ hiển thị một số định nghĩa và/hoặc ví dụ nhất định dựa trên thông tin đầu vào của người dùng. Nếu chỉ thông qua"đếm", nó sẽ hiển thị số lượng định nghĩa cụ thể mà không có ví dụ. Tương tự, việc chuyển “ví dụ” làm đối số sẽ đưa ra một định nghĩa cùng với một câu ví dụ. Trong trường hợp không có tùy chọn nào được chỉ định, hành vi mặc định sẽ chỉ hiển thị định nghĩa.

Để làm cho ứng dụng có thể thực thi được, hãy bắt đầu bằng cách kết hợp một dòng shebang ở đầu tệp bin/index.js, cho phép nó hoạt động như một tập lệnh độc lập.

 #!/usr/bin/env node 

Tiếp theo, điều hướng đến tệp pack.json trong thư mục dự án của bạn và sửa đổi nội dung của thuộc tính main. Ngoài ra, hãy thêm thuộc tính bin mới vào sau thuộc tính hiện có, như minh họa bên dưới:

 "main": "./bin/index.js",
"bin": {
  "urbanary-cli": "./bin/index.js"
},

Về bản chất, mấu chốt của việc thực hiện một dự án dựa trên Urbanary-cli nằm ở lệnh được nhập thông qua thiết bị đầu cuối. Do đó, điều bắt buộc là người ta phải sử dụng tiêu đề thích hợp cho lệnh đã nói trong khi phát triển các ứng dụng dòng lệnh.

Để cài đặt thành công ứng dụng trên toàn cầu bằng npm, người ta phải chạy lệnh “npm install-g” trong terminal của họ. Hành động này sẽ cho phép thực thi ứng dụng dưới dạng lệnh từ cùng một thiết bị đầu cuối.

Hình minh họa được cung cấp mô tả quy trình cài đặt và thực thi lệnh chẩn đoán nhằm xác định mục đích của mô-đun lmk.

/vi/images/terminal_output_for_install_run.jpg

Xuất bản tác phẩm của bạn trên sổ đăng ký npm (Trình quản lý gói nút) là một quy trình đơn giản cho phép phân phối rộng rãi và dễ dàng cài đặt dự án của bạn. Để thực hiện điều này, hãy điều hướng đến thư mục gốc của dự án của bạn và thực hiện lệnh “npm Publish” trong terminal. Bằng cách đó, dự án của bạn sẽ có sẵn để người khác dễ dàng cài đặt thông qua lệnh “npm install”.

Việc sử dụng Node.js tạo điều kiện thuận lợi cho việc phát triển và phổ biến các ứng dụng thay vì sử dụng Rust hoặc các công nghệ tương tự để xây dựng giao diện dòng lệnh.

Xây dựng các ứng dụng CLI chức năng với Node.js

Thật vậy, đối với những người tham gia phát triển gói npm yêu cầu tiện ích dòng lệnh bổ sung hoặc cho các nhà phát triển đang tìm cách nâng cao quy trình làm việc của họ thông qua việc tạo các công cụ tùy chỉnh, gói Node.js Commander cung cấp một giải pháp toàn diện để biến tầm nhìn của một người thành hiện thực.

Người ta có thể nâng cao trải nghiệm người dùng về giao diện dòng lệnh trong ứng dụng của mình thông qua việc sử dụng các thư viện bổ sung một cách dễ dàng nhờ tính linh hoạt và ổn định vốn có do Node.js cung cấp, đóng vai trò là nền tảng đáng tin cậy cho những nỗ lực đó mà không có sự phức tạp đáng kể.