使用Node.js構建交互式命令行工具
使用 Node.js 構建一個根據(jù)詢問創(chuàng)建文件的命令行工具。
當用于構建命令行界面(CLI)時,Node.js 十分有用。在這篇文章中,我將會教你如何使用 Node.js 來構建一個問一些問題并基于回答創(chuàng)建一個文件的命令行工具。
開始
首先,創(chuàng)建一個新的 npm 包(NPM 是 JavaScript 包管理器)。
mkdir my-scriptcd my-scriptnpm init
NPM 將會問一些問題。隨后,我們需要安裝一些包。
npm install --save chalk figlet inquirer shelljs
這是我們需要的包:
- Chalk:正確設定終端的字符樣式
- Figlet:使用普通字符制作大字母的程序(LCTT 譯注:使用標準字符,拼湊出圖片)
- Inquirer:通用交互式命令行用戶界面的集合
- ShellJS:Node.js 版本的可移植 Unix Shell 命令行工具
創(chuàng)建一個 index.js 文件
現(xiàn)在我們要使用下述內容創(chuàng)建一個 index.js 文件。
#!/usr/bin/env nodeconst inquirer = require("inquirer");const chalk = require("chalk");const figlet = require("figlet");const shell = require("shelljs");
規(guī)劃命令行工具
在我們寫命令行工具所需的任何代碼之前,做計劃總是很棒的。這個命令行工具只做一件事:創(chuàng)建一個文件。
它將會問兩個問題:文件名是什么以及文件后綴名是什么?然后創(chuàng)建文件,并展示一個包含了所創(chuàng)建文件路徑的成功信息。
// index.jsconst run = async () => {// show script introduction// ask questions// create the file// show success message};run();
***個函數(shù)只是該腳本的介紹。讓我們使用 chalk 和 figlet 來把它完成。
const init = () => {console.log(chalk.green(figlet.textSync("Node JS CLI", {font: "Ghost",horizontalLayout: "default",verticalLayout: "default"})));}const run = async () => {// show script introductioninit();// ask questions// create the file// show success message};run();
然后,我們來寫一個函數(shù)來問問題。
const askQuestions = () => {const questions = [{name: "FILENAME",type: "input",message: "What is the name of the file without extension?"},{type: "list",name: "EXTENSION",message: "What is the file extension?",choices: [".rb", ".js", ".php", ".css"],filter: function(val) {return val.split(".")[1];}}];return inquirer.prompt(questions);};// ...const run = async () => {// show script introductioninit();// ask questionsconst answers = await askQuestions();const { FILENAME, EXTENSION } = answers;// create the file// show success message};
注意,常量 FILENAME 和 EXTENSIONS 來自 inquirer 包。
下一步將會創(chuàng)建文件。
const createFile = (filename, extension) => {const filePath = `${process.cwd()}/${filename}.${extension}`shell.touch(filePath);return filePath;};// ...const run = async () => {// show script introductioninit();// ask questionsconst answers = await askQuestions();const { FILENAME, EXTENSION } = answers;// create the fileconst filePath = createFile(FILENAME, EXTENSION);// show success message};
***,重要的是,我們將展示成功信息以及文件路徑。
const success = (filepath) => {console.log(chalk.white.bgGreen.bold(`Done! File created at ${filepath}`));};// ...const run = async () => {// show script introductioninit();// ask questionsconst answers = await askQuestions();const { FILENAME, EXTENSION } = answers;// create the fileconst filePath = createFile(FILENAME, EXTENSION);// show success messagesuccess(filePath);};
來讓我們通過運行 node index.js 來測試這個腳本,這是我們得到的:

完整代碼
下述代碼為完整代碼:
#!/usr/bin/env nodeconst inquirer = require("inquirer");const chalk = require("chalk");const figlet = require("figlet");const shell = require("shelljs");const init = () => {console.log(chalk.green(figlet.textSync("Node JS CLI", {font: "Ghost",horizontalLayout: "default",verticalLayout: "default"})));};const askQuestions = () => {const questions = [{name: "FILENAME",type: "input",message: "What is the name of the file without extension?"},{type: "list",name: "EXTENSION",message: "What is the file extension?",choices: [".rb", ".js", ".php", ".css"],filter: function(val) {return val.split(".")[1];}}];return inquirer.prompt(questions);};const createFile = (filename, extension) => {const filePath = `${process.cwd()}/${filename}.${extension}`shell.touch(filePath);return filePath;};const success = filepath => {console.log(chalk.white.bgGreen.bold(`Done! File created at ${filepath}`));};const run = async () => {// show script introductioninit();// ask questionsconst answers = await askQuestions();const { FILENAME, EXTENSION } = answers;// create the fileconst filePath = createFile(FILENAME, EXTENSION);// show success messagesuccess(filePath);};run();
使用這個腳本
想要在其它地方執(zhí)行這個腳本,在你的 package.json 文件中添加一個 bin 部分,并執(zhí)行 npm link:
{"name": "creator","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","start": "node index.js"},"author": "","license": "ISC","dependencies": {"chalk": "^2.4.1","figlet": "^1.2.0","inquirer": "^6.0.0","shelljs": "^0.8.2"},"bin": {"creator": "./index.js"}}
執(zhí)行 npm link 使得這個腳本可以在任何地方調用。
這就是是當你運行這個命令時的結果。
/usr/bin/creator -> /usr/lib/node_modules/creator/index.js/usr/lib/node_modules/creator -> /home/hugo/code/creator
這會連接 index.js 作為一個可執(zhí)行文件。這是完全可能的,因為這個 CLI 腳本的***行是 #!/usr/bin/env node。
現(xiàn)在我們可以通過執(zhí)行如下命令來調用。
$ creator
總結
正如你所看到的,Node.js 使得構建一個好的命令行工具變得非常簡單。如果你希望了解更多內容,查看下列包。
在評論中留下你關于構建命令行工具的經(jīng)驗吧!






























