<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      命令行應(yīng)用開發(fā)初學(xué)者指南:腳手架篇、UI 庫和交互工具

      在日常的前端開發(fā)工作中,我們經(jīng)常依賴各種命令行工具來提高效率和代碼質(zhì)量。例如,create-react-appeslint 等工具不僅簡化了項(xiàng)目的初始化過程,還能自動執(zhí)行代碼檢查和格式化任務(wù)。當(dāng)我們使用這些工具時,它們通常會通過一系列互動式的問答來收集必要的信息,從而根據(jù)我們的選擇進(jìn)行相應(yīng)的配置和安裝。

      eslint 工具為例(如下圖所示),當(dāng)你首次運(yùn)行 eslint --init 命令時,它會引導(dǎo)你完成一系列選擇題,包括你使用的框架(如 ReactVue.js 或其他),以及其他配置選項(xiàng)。通過這種方式,eslint 能夠?yàn)槟闵梢粋€最適合項(xiàng)目需求的配置文件。

      本篇文章將介紹在開發(fā)命令行工具過程中常用的第三方庫。這些庫主要分為三類:

      • 腳手架框架:用于解析命令行參數(shù),例如 eslint --init 中的 --init。常用的腳手架框架有 yargscommand

      • 命令行輸出美化庫:基于 ANSI Escape 規(guī)范,用于對命令行輸出進(jìn)行顏色和樣式美化。常用的美化庫有 chalkora

      • 交互式命令行庫:用于創(chuàng)建交互式的命令行界面,例如 eslint 初始化過程中會提出的問答,如 "Which framework does your project use?"。常用的交互式命令行庫有 inquirer

      腳手架框架

      首先,讓我們簡單回顧一下 Node.js 腳手架的開發(fā)流程:

      • 創(chuàng)建 npm 項(xiàng)目:使用 npm init 命令創(chuàng)建一個新的 npm 項(xiàng)目,并填寫相關(guān)項(xiàng)目信息。
      • 創(chuàng)建腳手架入口文件:在項(xiàng)目根目錄下創(chuàng)建一個入口文件,例如 index.js,并在文件頂部添加 #!/usr/bin/env node 以便將其識別為可執(zhí)行文件。
      • 配置 package.json:在 package.json 文件中添加 bin 屬性,指定腳手架的入口文件路徑。
      • 添加 npm link:使用 npm link 命令將項(xiàng)目鏈接到全局環(huán)境中,這樣就可以在本地通過短指令訪問腳手架。

      詳細(xì)的創(chuàng)建及實(shí)現(xiàn)功能邏輯可以參考文章《Node.js 構(gòu)建命令行工具:實(shí)現(xiàn) ls 命令的 -a 和 -l 選項(xiàng)》

      例如,假設(shè)我們創(chuàng)建了一個名為 ice-cli 的項(xiàng)目,并在其中添加了 --init 指令的執(zhí)行邏輯。那么,我們?nèi)绾沃烙脩糨斎肓诉@項(xiàng)指令呢?這就需要我們在項(xiàng)目中解析命令行參數(shù)。

      自行解析參數(shù)

      Node.js 中,我們可以利用內(nèi)置的 process 對象來解析命令行參數(shù)。具體來說,可以在入口文件 index.js 中執(zhí)行以下代碼:

      const argv = require("process").argv;
      console.log("argv", argv);
      

      當(dāng)用戶在命令行中輸入 ice-cli create project --help 這一長串指令后,通過 process.argv 獲取到的是一個數(shù)組。數(shù)組的第一個元素代表 Node.js 的執(zhí)行路徑,第二個元素代表當(dāng)前指令文件的路徑,從第三個元素開始則是用戶輸入的內(nèi)容。

      例如,對于命令 ice-cli create project --help,process.argv 的輸出可能如下所示:

      [
          '/usr/local/bin/node', // Node.js 執(zhí)行路徑
          '/usr/local/lib/node_modules/ice-cli/index.js', // 當(dāng)前指令文件路徑
          'create', // 用戶輸入的第一個參數(shù)
          'project', // 用戶輸入的第二個參數(shù)
          '--help' // 用戶輸入的第三個參數(shù)
      ]
      

      拿到用戶輸入的內(nèi)容后,我們需要對其進(jìn)行進(jìn)一步的拆分和處理。用戶輸入的內(nèi)容通常包括 命令(command)選項(xiàng)(options)。例如,在命令 webpack config ./webpack.config.js 中,config 是命令,./webpack.config.js 是命令后面的參數(shù);而在命令 webpack --help 中,--help 是選項(xiàng)。

      通過解析 process.argv 數(shù)組,我們可以提取出命令和選項(xiàng),并根據(jù)它們執(zhí)行相應(yīng)的邏輯。例如:

      const command = argv[2];  // 獲取命令
      const args = argv.slice(3);  // 獲取命令后面的參數(shù)
      
      if (command === 'create') {
        if (args.includes('--help')) {
          console.log('Usage: ice-cli create <project-name>');
        } else {
          const projectName = args[0];
          console.log(`Creating project ${projectName}...`);
        }
      }
      

      在日常開發(fā)中,我們通常不會自己去解析命令行參數(shù),因?yàn)檫@涉及到大量的邊界情況和錯誤處理。使用社區(qū)廣泛認(rèn)可的第三方庫可以更加高效和嚴(yán)謹(jǐn)。其中,yargscommander 是兩個非常優(yōu)秀的推薦庫。

      yargs

      yargs 是一個功能強(qiáng)大且易于使用的命令行參數(shù)解析庫。它提供了豐富的 API,可以幫助你輕松地解析命令和選項(xiàng),并生成詳細(xì)的幫助信息。

      安裝 yargs

      首先,通過 npm 安裝 yargs

      npm install yargs
      

      實(shí)現(xiàn) --help 和 --version 功能

      通過簡單的代碼就可以實(shí)現(xiàn) --help--version 功能:

      const yargs = require("yargs/yargs");
      const { hideBin } = require("yargs/helpers");
      const arg = hideBin(process.argv);
      yargs(arg).argv;
      

      運(yùn)行 ice-cli --help ,結(jié)果如下圖所示:

      常用屬性

      yargs 采用鏈?zhǔn)秸{(diào)用的方式為命令設(shè)置屬性。以下是一些常用的屬性:

      • usage() :在輸入 --help 時會顯示的提示信息。
      • demandCommand() :最少要輸入的命令數(shù)量,以及當(dāng)沒有輸入命令時的提示。
      • recommendCommands() :如果輸入的指令不完整,會給出最近似命令的提示,例如:“Did you mean xx?”
      • strict() :嚴(yán)格模式,輸入錯誤命令時會給出提示。
      • alias() :為指令取別名。
      • options() :定義多個全局選項(xiàng),在任何場景都可以訪問到。
      • option() :定義單個全局選項(xiàng),在任何場景都可以訪問到。
      • group() :將一些命令聚合到一個分類中。
      • command() :定義指令。
      • epilogue() :定義結(jié)尾信息。

      示例代碼

      將上述命令組合起來,示例如下:

      const yargs = require("yargs/yargs");
      const { hideBin } = require("yargs/helpers");
      const arg = hideBin(process.argv);
      const cli = yargs(arg);
      cli
        .usage("Usage: ice-ls [command] <options>")
        .demandCommand(
          1,
          "A command is required. Pass --help to see all avaiable commands and options."
        )
        .recommendCommands()
        .strict()
        .alias("h", "help")
        .options({
          debug: {
            type: "boolean",
            describe: "Bootstarap debug mode",
            alias: "d",
          },
        })
        .group(["debug"], "Dev options:")
        .command({
          command: "list",
          aliases: ["ls", "la", "ll"],
          describe: "List total packages",
          builder: (argv) => {
            console.log("builder", argv);
          },
          handler: (argv) => {
            console.log("handler", argv);
          },
        })
        .epilogue("You own footer description").argv;
      

      當(dāng)執(zhí)行 ice-ls 命令時,輸出如下:

      • 第一行出現(xiàn) usage 函數(shù)配置的提示:Usage: ice-ls [command]
      • 接著是 command 函數(shù)配置的指令 list,以及它的別名 ls, la, ll。
      • 然后是通過 group 函數(shù)分組的 Dev options。
      • 下面是 yargs 默認(rèn)提供的選項(xiàng) --version 和 --help。
      • 接著是 epilogue 函數(shù)配置的尾部描述。
      • 最后一行是 demandCommand 提示: A command is required. Pass --help to see all avaiable commands and options。因?yàn)閳?zhí)行命令 ice-ls 的時候沒有提供具體指令。

      執(zhí)行 ice-cli listice-ls list --debug,此時程序進(jìn)入 command 函數(shù)中,執(zhí)行 builder 函數(shù) 和 handler 函數(shù),可以在這里編寫實(shí)際的功能邏輯。

      commander

      commander 也是一個功能強(qiáng)大的命令行參數(shù)解析庫,但它在使用方式和 API 設(shè)計(jì)上和 yargs 有一些差異。

      安裝 commander

      首先,通過 npm 安裝 commander

      npm install commander
      

      實(shí)現(xiàn) --help 和 --version 功能

      commander 通過簡單的配置就可以生成 usage 提示以及 --help--version 功能。

      const commander = require("commander");
      const pkg = require("../package.json");
      const program = new commander.Command();
      program
        .name(Object.keys(pkg.bin)[0])
        .usage("<command> [options]")
        .version(pkg.version);
      
      program.parse(process.argv);
      

      執(zhí)行上述代碼后,運(yùn)行 ice-cli --help 的輸出如下所示:

      Usage: ice-cli <command> [options]
      
      Options:
        -V, --version  output the version number
        -h, --help     display help for command
      

      注冊指令

      commanderyargs 在注冊指令的語法上有一些區(qū)別。yargs 使用鏈?zhǔn)秸{(diào)用,而 commander 注冊指令后返回值并不是自身,因此不能通過鏈?zhǔn)秸{(diào)用來注冊多個指令。

      // 注冊 clone 命令
      program
        .command("clone <source> [destination]")
        .description("clone a repository")
        .option("-f --force", "是否強(qiáng)制克隆")
        .usage("[options]")
        .action((source, destination, cmdObj) => {
          console.log("do clone", source, destination);
        });
        
      // 劫持所有未定義的指令
      program
        .arguments("<cmd> [options]")
        .description("test command", {
          cmd: "command to run",
          options: "options for command",
        })
        .action((cmd, options) => {
          console.log(cmd, options);
        });  
      

      當(dāng)執(zhí)行 ice-cli clone a b 時,輸出為 "do clone a b"。當(dāng)執(zhí)行 ice-cli create c 時,輸出為 "create c"。

      注冊子命令

      commander 注冊子命令的方式也非常簡單。以下是一個示例:

      const service = new commander.Command("service");
      service
        .command("start [port]")
        .description("start service at some port")
        .action((port) => {
          console.log('>>>service start', port)
        });
      service
        .command("stop")
        .description("stop service")
        .action(() => {
          console.log('>>>service stop')
        });
      

      當(dāng)執(zhí)行 ice-cli service start 8000 時,會輸出 ">>>service start 8000"。當(dāng)執(zhí)行 ice-cli service stop 時,會輸出 ">>>service stop"。

      yargscommander 解析命令行參數(shù),生成幫助信息,并注冊命令。它們提供了強(qiáng)大的命令行接口構(gòu)建能力,使得命令行工具更加靈活和易用。

      命令行輸出美化庫

      在進(jìn)行命令行交互時,經(jīng)常需要對某些內(nèi)容加粗、加字體顏色,以區(qū)分用戶選中的內(nèi)容和需要重點(diǎn)關(guān)注的問題。為了實(shí)現(xiàn)這些效果,存在一個命令行渲染標(biāo)準(zhǔn),稱為 ANSI escape code。此外,還有一些成熟的第三方庫,如 chalkora,可以幫助我們更方便地實(shí)現(xiàn)這些功能。

      ANSI escape code

      ANSI escape code 是一種用于控制終端輸出的標(biāo)準(zhǔn)。通過特定的編碼序列,可以在命令行中實(shí)現(xiàn)顏色、加粗等效果。

      示例

      在 bin 文件夾下創(chuàng)建 ansi.js 文件,文件中定義如下代碼:

      console.log("\x1B[31mThis text is red\x1B[0m");
      

      通過 node 執(zhí)行該 JS 文件,顯示的是紅色文本,內(nèi)容為 "This text is red"。如圖所示:

      編碼解析

      即使我們沒有借助任何第三方庫,僅通過一行文本就能實(shí)現(xiàn)命令行中的顏色和樣式變化。這一行看似“亂碼”的文本實(shí)際上是由 ANSI Escape Codes 組成的。下面是對這些字符的詳細(xì)拆解:

      • \x1B:這是轉(zhuǎn)義字符,表示 ASCII 值為 27 的字符,也常表示為 ESC。它是所有 ANSI Escape Codes 的前綴。
      • [:這是一個分隔符,表示接下來是一個控制序列。
      • 31:這是一個數(shù)字代碼,表示設(shè)置前景色為紅色。
      • m:這是一個終止符,表示控制序列的結(jié)束。
      • \x1B[0m:重置所有文本屬性,包括顏色和樣式。

      查找期望的樣式

      要找到期望的樣式,可以在 ansi escape code 官網(wǎng) 查找。例如,31 代表紅色前景色,41 代表紅色背景色。

      雖然可以直接使用 ANSI Escape Codes 來實(shí)現(xiàn)顏色和樣式變化,但在實(shí)際開發(fā)中這樣做會非常繁瑣。你需要手動定義轉(zhuǎn)義字符、分隔符,還要查找每個顏色對應(yīng)的編碼。幸運(yùn)的是,已經(jīng)有成熟的第三方庫可以幫助我們解決這些問題,例如 chalkora

      chalk

      chalk 是一個用于顏色渲染的庫,其語法非常簡單,通過方法名就能知道其用途。常見的方法包括:

      • rgb(r, g, b):定義自定義顏色。
      • blue:設(shè)置藍(lán)色字體。
      • bold:設(shè)置字體加粗。
      • green:設(shè)置綠色字體。
      • underline:設(shè)置下劃線。

      這些方法名與 CSS 中的樣式名稱相似,使得使用起來非常直觀。chalk 支持多種使用形式,包括直接使用、拼接、鏈?zhǔn)秸{(diào)用、傳入多個參數(shù)和嵌套調(diào)用。

      安裝

      首先通過 npm 安裝 chalk

      npm install chalk
      

      基本使用

      chalk 是以 ES module 方式實(shí)現(xiàn)的,需要通過 import 方式引入。如果希望在 Node.js 環(huán)境中運(yùn)行,可以將文件后綴名定義為 .mjs

      例如以下代碼:

      import chalk from "chalk";
      
      // 直接使用
      console.log("hello chalk");
      // 定義自定義顏色
      console.log(chalk.rgb(255, 0, 0)("hello nodejs"));
      // 拼接不同樣式
      console.log(chalk.blue.bold("hello ") + chalk.green("world"));
      // 使用十六進(jìn)制顏色
      console.log(chalk.hex("#ff0000")("it is a nice day"));
      // 鏈?zhǔn)秸{(diào)用和嵌套調(diào)用
      console.log(
        chalk.green(
          "I am a green line " +
          chalk.blue.underline.bold("with a blue substring") +
          " that becomes green again!"
        )
      );
      

      執(zhí)行上述代碼后,命令行中的輸出效果如下所示:

      ora

      ora 是一個用于顯示加載動畫的庫,非常適合在命令行應(yīng)用中顯示進(jìn)度和狀態(tài)。它以 ES module 方式導(dǎo)出,需要定義 .mjs 文件。

      安裝

      首先通過 npm 安裝 ora

      npm install ora
      

      基本使用

      ora 在使用時需要手動調(diào)用開始和結(jié)束方法。以下是一個簡單的示例,顯示一個加載動畫:

      import ora from "ora";
      const spinner = ora({
        text: "loading",
        spinner: "dots",
      }).start();
      

      執(zhí)行上述代碼后,命令行中會顯示一個持續(xù)的加載動畫,如下圖所示:

      自定義屬性

      ora 還支持定義其他屬性,如加載動畫效果、顏色、前綴文本等。

      屬性說明:

      • text:初始加載文本。
      • spinner:加載動畫效果,可以是一個預(yù)定義的字符串(如 dots、line 等)或自定義對象。
      • color:加載動畫的顏色。
      • prefixText:加載文本的前綴。
      • start():啟動加載動畫。
      • stop():停止加載動畫。
      • succeed(message):停止加載動畫并顯示成功消息。
      • fail(message):停止加載動畫并顯示失敗消息。
      • warn(message):停止加載動畫并顯示警告消息。
      • info(message):停止加載動畫并顯示信息消息。

      以下是一個更復(fù)雜的示例,展示了如何動態(tài)更新加載文本并最終停止加載動畫:

      import ora from "ora";
      const spinner = ora({
        text: "loading",
        spinner: "dots",
      }).start();
      
      // 設(shè)置加載顏色和前綴文本
      spinner.color = "red";
      spinner.prefixText = "download ora:";
      
      let percent = 0;
      let task = setInterval(() => {
        percent += 10;
        spinner.text = "Loading..." + percent + "%";
        if (percent === 100) {
          spinner.stop();
          spinner.succeed("download success");
          clearInterval(task);
        }
      }, 1000);
      

      按以上邏輯,執(zhí)行過程的中間態(tài)如下所示:

      交互式命令行

      在命令行應(yīng)用中,經(jīng)常會涉及到一些交互邏輯,例如在 eslint 初始化過程中會詢問用戶當(dāng)前使用的框架是 ReactVue 還是其他框架。用戶可以通過鍵盤的上下左右鍵和回車進(jìn)行選擇。inquirer 就是這樣一個用于命令行交互的第三方庫。

      inquirer

      安裝

      inquirer 是一個強(qiáng)大的命令行交互庫,可以輕松地創(chuàng)建用戶友好的命令行界面。

      npm install inquirer
      

      基本使用

      以下是一個簡單的示例,展示了如何使用 inquirer 創(chuàng)建一個列表選擇:

      import inquirer from "inquirer";
      
      inquirer
        .prompt([
          {
            type: "list",
            name: "language",
            message: "language",
            choices: [
              {
                value: 1,
                name: "react",
              },
              {
                value: 2,
                name: "vue",
              },
              {
                value: 3,
                name: "angular",
              },
            ],
      
          },
        ])
        .then((res) => {
          console.log("anwser", res);
        });
      

      執(zhí)行上述代碼后,命令行中會出現(xiàn)一個選擇列表,如下圖所示:

      多種交互類型

      inquirer 支持多種交互類型,不僅限于列表選擇,還可以輸入文本、密碼、多選等。
      以下是一個示例,展示了多種類型的交互問題:

      
      import inquirer from "inquirer";
      inquirer
        .prompt([
          {
            type: "input",
            name: "yourName",
            message: "Your name",
          },
          {
            type: "list",
            name: "language",
            message: "language",
            choices: [
              {
                value: 1,
                name: "react",
              },
              {
                value: 2,
                name: "vue",
              },
              {
                value: 3,
                name: "angular",
              },
            ],
          },
          {
            type: "expand",
            name: "color",
            message: "color",
            choices: [
              {
                key: "R",
                value: "red",
              },
              {
                key: "G",
                value: "green",
              },
              {
                key: "B",
                value: "blue",
              },
            ],
          },
          {
            type: "checkbox",
            name: "fruits",
            message: "fruits",
            choices: [
              {
                value: 1,
                name: "apple",
              },
              {
                value: 2,
                name: "banana",
              },
              {
                value: 3,
                name: "orange",
              },
            ],
          },
          {
            type: "password",
            name: "password",
            message: "password",
          },
        ])
        .then((res) => {
          console.log("anwser", res);
        });
      

      執(zhí)行上述代碼后,命令行中會依次顯示多個交互問題,最終,所有的用戶輸入都會在 then 方法中統(tǒng)一獲取,如下圖所示:

      通過 inquirer,你可以輕松地在命令行應(yīng)用中實(shí)現(xiàn)各種交互邏輯。其豐富的交互類型和靈活的校驗(yàn)機(jī)制使得 inquirer 成為一個非常實(shí)用的命令行交互庫。

      通過結(jié)合這些工具和庫,可以輕松地構(gòu)建出功能強(qiáng)大、用戶體驗(yàn)良好的命令行應(yīng)用。

      如果你對前端工程化有興趣,或者想了解更多相關(guān)的內(nèi)容,歡迎查看我的其他文章,這些內(nèi)容將持續(xù)更新,希望能給你帶來更多的靈感和技術(shù)分享~

      posted @ 2024-11-27 21:18  一顆冰淇淋  閱讀(559)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲成人av综合一区| 夜夜添无码试看一区二区三区| 加勒比亚洲天堂午夜中文| 香蕉EEWW99国产精选免费| 欧美日产国产精品日产| 亚洲成人av在线系列| 久久精品国产亚洲av麻豆小说| 日本一区二区三区免费播放视频站| 日韩a无v码在线播放| 一区二区亚洲人妻av| 福利一区二区视频在线| 熟妇人妻不卡中文字幕| 成人区人妻精品一区二蜜臀| 久热这里有精彩视频免费| 老色鬼在线精品视频在线观看| 亚洲 日韩 国产 制服 在线| 九九热精品在线免费视频| 国产在线不卡精品网站| 精品日本免费一区二区三区| 久久国产精品第一区二区| 欧美牲交a欧美牲交aⅴ免费真| 成人国产精品一区二区网站公司| 2019香蕉在线观看直播视频| 99国精品午夜福利视频不卡99| 狠狠躁夜夜躁人人爽天天| 成人爽a毛片免费| 东方av四虎在线观看| 亚洲乱码国产乱码精品精大量| 国产熟妇另类久久久久久| 成人激情视频一区二区三区| 无码专区视频精品老司机| 日本中文字幕在线播放| 国产精品内射在线免费看| 亚洲区福利视频免费看| 亚洲一区二区精品极品| 国产成人a∨激情视频厨房| 国产综合有码无码中文字幕| 水富县| 亚洲午夜av一区二区| 久久精品国产福利一区二区| 淮滨县|