<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 Node,如何制作一個(gè)專業(yè)的命令行工具?

          共 6010字,需瀏覽 13分鐘

           ·

          2021-11-16 19:14

          使用 Node 開發(fā)一個(gè)命令行工具很有意思,較為其它語言而言也更加簡單,今天山月寫一篇文章總結(jié)一下如何寫一個(gè)友好且健壯的 cli 工具。

          在閱讀完本篇文章之后,「強(qiáng)烈推薦閱讀」 Github 上的一篇文章: Node CLI 工具最佳實(shí)踐。正如它的標(biāo)題而言,在 Github 上用于 2000 顆星星的該文章的確稱得上最佳實(shí)踐。

          長按識(shí)別二維碼查看原文

          標(biāo)題:Node CLI 工具最佳實(shí)踐 ? ? ?

          「目錄」

          • 1. 命令行工具與環(huán)境變量 PATH

          • 2. 原理

          • 3. 從 package.json 說起

          • 4. 一個(gè)執(zhí)行環(huán)境

          • 5. 解析命令輸入

          • 6. 用戶體驗(yàn)與豐富的色彩

          • 7. 可交互性

          • 8. 發(fā)布與安裝

          • 9. 總結(jié)

          1. 命令行工具與環(huán)境變量 PATH

          什么是命令行工具?

          最初印象大致是 ls,pwd 這些能夠「在終端執(zhí)行的系統(tǒng)命令」,這樣的命令很多,數(shù)不勝數(shù),被稱為系統(tǒng)內(nèi)置命令。

          如果使用 which 查看他們的來歷,則能夠發(fā)現(xiàn)他們的廬山真面目:

          # 由此可知,pwd 為一個(gè)系統(tǒng)內(nèi)置命令
          $ which pwd
          pwd: shell built-in command

          隨著對(duì) Linux/Unix 系統(tǒng)理解及使用的逐漸加深,發(fā)現(xiàn)了諸多的非內(nèi)置命令:

          • top

          • ps

          • netstat

          • dig

          • man

          使用 which 追根究底,發(fā)現(xiàn)它們實(shí)際執(zhí)行的路徑在某一個(gè) bin 目錄

          $ which top
          /usr/bin/top

          $ which ps
          /bin/ps

          而這些 bin 目錄在環(huán)境變量 PATH 中,豁然開朗。簡而言之: 「在環(huán)境變量的 PATH 中路徑的命令可在其它任意地方執(zhí)行」。

          export PATH=$HOME/bin:/usr/local/bin:$PATH

          說起環(huán)境變量,你可以使用 env 列出所有的環(huán)境變量。

          $ env
          LANG=zh_CN.UTF-8
          USER=root
          LOGNAME=root
          HOME=/root
          PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

          你好像想起點(diǎn)什么?在大學(xué)配置 Java 時(shí)被環(huán)境變量支配的各種恐懼?

          是了,所有語言的可執(zhí)行命令都要放在 PATH 下,只不過其它語言的安裝工具自動(dòng)給你做了這件事,而 Java 讓你自己來處理它。

          • java

          • python

          • pip

          • node

          • npm

          「開發(fā)命令行的原理也是如此,將你開發(fā)的命令行工具腳本置于環(huán)境變量 PATH 下的路徑之中」,而本篇文章的目標(biāo)就是:

          使用 Javascript 這門前端開發(fā)者熟悉的語言,借助 Node 環(huán)境,開發(fā)一個(gè)命令行工具。

          2. 原理

          先看兩個(gè) Node 的命令行工具:

          • [serve](https://github.com/vercel/serve) 一個(gè)流行的靜態(tài)文件服務(wù)器,大名鼎鼎 Vercel 團(tuán)隊(duì)(Next.js 團(tuán)隊(duì))的力作

          • markdown 一個(gè)山月自己寫的解析 URL 到 markdow 的命令行。通過命令解析出他們指向的符號(hào)鏈接

          $ ls -lah $(which serve)
          lrwxr-xr-x 1 xiange admin 65B 7 12 2020 /usr/local/bin/serve -> ../../../Users/shanyue/.config/yarn/global/node_modules/.bin/serve

          $ ls -lah $(which markdown)
          lrwxr-xr-x 1 xiange admin 48B 1 28 20:06 /usr/local/bin/markdown -> ../lib/node_modules/markdown-read/md-read-cli.js

          從中可以看出關(guān)于 Node 全局命令行的原理:

          1. npm 全局下載某個(gè) package 到路徑 /usr/local/lib/node_modules 下 (yarn 同理,對(duì)應(yīng)路徑 ~/.config/yarn/global/node_modules)

          2. 根據(jù)該庫的 package.json 中 bin 字段的指示,把對(duì)應(yīng)的命令行路徑通過符號(hào)索引掛載到 PATH 路徑

          3. 對(duì)應(yīng)的二進(jìn)制腳本添加 x 權(quán)限 (可執(zhí)行文件權(quán)限)

          簡而言之,Node 環(huán)境下的命令行工具,借助的原理無非是「環(huán)境變量 Path」與一個(gè)「符號(hào)鏈接」

          3. 從 package.json 說起

          「package.json 中的 bin 字段」,用以指定最終的命令行工具的名字

          {
          "bin": {
          "serve": "./bin/serve.js"
          }
          }

          如上所示,server 是最終在終端執(zhí)行的命令,而 ./bin/serve.js 是該命令實(shí)際執(zhí)行的腳本文件。

          對(duì)于最終可執(zhí)行的命令行工具,Node 項(xiàng)目一般傾向置文件于 bin 目錄下,如以下 Typescript 關(guān)于它命令行的配置:

          {
          "bin": {
          "tsc": "./bin/tsc",
          "tsserver": "./bin/tsserver"
          },
          }

          4. 一個(gè)執(zhí)行環(huán)境

          對(duì)于可直接執(zhí)行的文件,需要指明執(zhí)行環(huán)境,首行添加一行說明:

          #!/usr/bin/env node

          // code 往下寫

          這一句話是啥子意思了?

          1. #! 加解釋器,標(biāo)明該文件使用 /usr/bin/env node 來執(zhí)行

          2. /usr/bin/env 為 env 的絕對(duì)路徑,用以在 PATH 路徑中執(zhí)行命令 (在各種不同的系統(tǒng)中,node 命令行的位置不同,因此使用 env node 找到路徑并執(zhí)行)

          3. env node 在人為層面可理解為執(zhí)行 node 命令

          所以這句話的意思是: 「使用 node 解釋器來執(zhí)行這個(gè)腳本,而通過 env node 能夠正確定位到 node 解釋器的位置」

          // 如果不寫 #!/usr/bin/env node,需要這么執(zhí)行
          $ node serve .

          // 如果寫上 #!/usr/bin/env node,可以直接執(zhí)行
          $ serve .

          5. 解析命令輸入

          在服務(wù)端應(yīng)用中,可以通過 request.url.querystringrequest.body 獲取用戶輸入。

          而在命令行工具中,可通過 progress.argv 可獲取用戶輸入。請(qǐng)看以下示例:

          $ node cmd.js 1 2 3
          // Output: [
          // '/usr/local/bin/node',
          // '/Users/shanyue/cmd.js',
          // '1',
          // '2',
          // '3',
          // ]
          process.argv

          根據(jù)解析 process.argv 可以定制格式來獲取各式各樣的參數(shù)作為命令行的輸入。`

          當(dāng)然解析參數(shù)也要參照 POSIX 兼容的基本規(guī)律: 格式、可選、必選、簡寫、說明、幫助等等。命令行工具命名協(xié)議 文章中已說的足夠詳細(xì)。

          長按識(shí)別二維碼查看原文

          標(biāo)題:命令行工具命名協(xié)議 ? ? ?
          // 一個(gè)較為規(guī)整的命令行幫助
          $ node --help
          Usage: node [options] [ script.js ] [arguments]
          node inspect [options] [ script.js | host:port ] [arguments]

          Options:
          - script read from stdin (default if no file name is provided,
          interactive mode if a tty)
          -- indicate the end of node options
          --abort-on-uncaught-exception aborting instead of exiting causes a core file to be generated for
          analysis
          -c, --check syntax check script without executing
          --completion-bash print source-able bash completion script
          --cpu-prof Start the V8 CPU profiler on start up, and write the CPU profile to
          disk before exit. If --cpu-prof-dir is not specified, write the profile
          to the current working directory.

          因?yàn)?POSIX 兼容繁雜的規(guī)則,以此衍生出了關(guān)于解析命令參數(shù)的多個(gè)庫,站在巨人的肩膀上,在實(shí)際工作中就直接開用吧!

          • yargs: Star 8.5K,周下載量 4900K

            長按識(shí)別二維碼查看原文

            標(biāo)題:yargs ? ? ?
          • commander: Star 19.7K,周下載量 5300K,tj 大神的作品

            長按識(shí)別二維碼查看原文

            標(biāo)題:commander ? ? ?

          以下是一個(gè) Demo: 使用 commander 解析不同的輸入指令

          const { program } = require('commander')

          // 解析不同的指令輸入
          program
          .option('-d, --debug', 'output extra debugging')
          .option('-s, --small', 'small pizza size')
          .option('-p, --pizza-type ', 'flavour of pizza')

          program.parse(process.argv)

          const options = program.opts()
          console.log(options)

          6. 用戶體驗(yàn)與豐富的色彩

          77c09361386912f8b48df65838fc23e6.webpNext 構(gòu)建輸出

          以上是 next build 命令行的標(biāo)準(zhǔn)輸出,擁有色彩多樣的高亮格式與豐富的列表展示,可以提供更豐富的用戶體驗(yàn)。

          目前大部分終端已支持彩色輸出,即通過 ANSI 編碼進(jìn)行控制,并擁有成熟的庫控制色彩。如 ansi-styles

          長按識(shí)別二維碼查看原文

          標(biāo)題:ansi-styles ? ? ?
          import styles from 'ansi-styles';

          console.log(`${styles.green.open}Hello world!${styles.green.close}`);

          豐富的高亮色彩如同代碼高亮一樣使用戶可以快速抓住重點(diǎn)。把異常、警告、成功的信息用不同的顏色標(biāo)出,命令行工具的輸出一目了然。在現(xiàn)代構(gòu)建工具,如 Webpack 下,也大都支持彩色輸出。

          以下是在命令行工具中常用的兩個(gè)較為高級(jí)的色彩庫,支持多種多樣色彩的輸出,當(dāng)然基本原理仍是 ANSI 編碼。

          • chalk

            長按識(shí)別二維碼查看原文

            標(biāo)題:chalk ? ? ?
          • colors

            長按識(shí)別二維碼查看原文

            標(biāo)題:colors ? ? ?

          以下是 chalk 示例,ErrorWarning 信息用不同的顏色表示

          const chalk = require('chalk')

          const error = chalk.bold.red
          const warning = chalk.keyword('orange')

          console.log(error('Error!'))
          console.log(warning('Warning!'))

          7. 可交互性

          在 Web 中,可使用 Input 來展現(xiàn)豐富多彩的表單,如開關(guān)、多選、單選、輸入框等。

          而在命令行工具中,也可借用多種庫來實(shí)現(xiàn)強(qiáng)交互性。

          • enquirer

            長按識(shí)別二維碼查看原文

            標(biāo)題:enquirer ? ? ?
          • ora

            長按識(shí)別二維碼查看原文

            標(biāo)題:ora ? ? ?
          • ink

            長按識(shí)別二維碼查看原文

            標(biāo)題:ink ? ? ?

          8. 發(fā)布與安裝

          在辛苦努力寫完一個(gè) cli 工具后,就是檢驗(yàn)成果的時(shí)候。發(fā)布到 npm 倉庫,可使所有人使用你的命令行工具,這也是最重要的一步

          # 發(fā)布之前需要 npm login,登錄到 npm registory
          $ npm publish

          發(fā)版成功后全局下載命令行工具,開始使用,示例用它抓取下我的博客首頁

          $ npm i -g markdown-read
          /usr/local/bin/markdown -> /usr/local/lib/node_modules/markdown-read/md-read-cli.js
          + [email protected]
          added 102 packages from 72 contributors and updated 10 packages in 33.15s

          $ markdown https://shanyue.tech
          ## [#](#山月的瑣碎博客記錄) 山月的瑣碎博客記錄

          本博客關(guān)于平常工作中在前端,后端以及運(yùn)維中遇到問題的一些文章總結(jié)。以后也會(huì)做系列文章進(jìn)行輸出,如前端高級(jí)進(jìn)階系列,個(gè)人服務(wù)器指南系列。個(gè)人微信 shanyue94,歡迎添加交流

          ## [#](#名字由來) 名字由來

          9. 總結(jié)

          本篇文章由淺至深講解了以下幾方面的內(nèi)容:

          1. 一個(gè)全局可執(zhí)行的命令行工具的原理是什么

          2. 在 Node 中開發(fā)一個(gè)命令行工具所需要的配置

          3. 開發(fā)命令行工具時(shí)如何解析參數(shù)

          并根據(jù)實(shí)踐,開發(fā)了一個(gè)從 URL 中讀取 Markdown 的小工具: markdown-read,歡迎 Star、下載及使用。

          長按識(shí)別二維碼查看原文

          標(biāo)題:markdown-read ? ? ?

          另外,我基于此命令行做了一個(gè) Web 版,歡迎來體驗(yàn): https://devtool.tech/html-md

          348f08595611e9dd099fced2f2ff54ce.webpHTML To Markdown 網(wǎng)頁版


          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲国产精品二二三三区 | 天天做爱网站 | 青娱乐免费偷拍视频播放 | 北条麻妃人妻上门在线播放 | 超碰碰免费网站 |