掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
最近山月開(kāi)發(fā)了一個(gè)從任意 URL 解析內(nèi)容并生成 markdown 的小客戶(hù)端工具: markdown-read。用以我個(gè)人公眾號(hào)的內(nèi)容獲取及一些優(yōu)質(zhì)內(nèi)容的整理收藏,歡迎 Star、下載及使用。

- $ markdown https://juejin.cn/post/6924258563862822919 | head -10
- > 本文作者:Wind、Skyler、ZRJ、ZJ
- ## 前言
- Webpack5 在 2020 年 10 月 10 日正式發(fā)布,并且在過(guò)去的幾個(gè)月中快速演進(jìn)和迭代,截止 1 月 28 日,Webpack5 已經(jīng)更新了 18 個(gè) minor 版本,帶來(lái)了許多十分吸引人的新特性。據(jù)[官網(wǎng)介紹](https://webpack.js.org/blog/2020-10-10-webpack-5-release/#general-direction "官網(wǎng)介紹"),Webpack5 整體的方向性變化有以下幾點(diǎn):
- 
- + 通過(guò)持久化硬盤(pán)緩存能力來(lái)提升構(gòu)建性能
- + 通過(guò)更好的算法來(lái)改進(jìn)長(zhǎng)期緩存(降低產(chǎn)物資源的緩存失效率)
想到用 Node 開(kāi)發(fā)一個(gè)命令行工具在工作中也較為常見(jiàn),也很有意思,總結(jié)一下
命令行工具
什么是命令行工具?
最初印象大致是 ls,pwd 這些能夠在終端執(zhí)行的系統(tǒng)命令,這樣的命令有很多,數(shù)不勝數(shù),被稱(chēng)為系統(tǒng)內(nèi)置命令。如果使用 which 查看他們的來(lái)歷,則能夠發(fā)現(xiàn)他們的廬山真面目:
- $ which pwd
- pwd: shell built-in command
隨著對(duì) Linux/Unix 系統(tǒng)理解及使用的逐漸加深,發(fā)現(xiàn)了諸多的非內(nèi)置命令:
使用 which 偵查情況,發(fā)現(xiàn)他們實(shí)際執(zhí)行的路徑在某一個(gè) bin 目錄
- $ which top
- /usr/bin/top
- $ which ps
- /bin/ps
而這些 bin 目錄在環(huán)境變量 PATH 中,豁然開(kāi)朗。簡(jiǎn)而言之: 在 PATH 中路徑的命令可在其它任意地方執(zhí)行。
- export PATH=$HOME/bin:/usr/local/bin:$PATH
你好像想起點(diǎn)什么?在大學(xué)配置 Java 時(shí)被環(huán)境變量支配的各種恐懼?是了,所有語(yǔ)言的可執(zhí)行命令都要放在 PATH 下,只不過(guò)其它語(yǔ)言自動(dòng)給你做了,而 Java 讓你自己做這件事。
開(kāi)發(fā)命令行的原理也是如此,而本篇文章的目標(biāo)就是:
使用 Javascript 這門(mén)前端開(kāi)發(fā)者熟悉的語(yǔ)言,借助 Node 環(huán)境,開(kāi)發(fā)一個(gè)命令行工具。
原理
先看兩個(gè)命令行工具: serve 一個(gè)流行的靜態(tài)文件服務(wù)器,markdown 一個(gè)我自己寫(xiě)的解析 URL 到 markdow 的命令行。通過(guò)命令解析出他們指向的符號(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)于命令行的解析:
簡(jiǎn)而言之,Node 環(huán)境下的命令行工具,借助的原理無(wú)非是環(huán)境變量 Path 與一個(gè)符號(hào)鏈接
從 package.json 說(shuō)起
在 package.json 中的 bin 選項(xiàng),用以指定最終的命令行工具的名字
- {
- "bin": {
- "markdown": "./md-read-cli"
- }
- }
如上所示,markdown 是最終在終端執(zhí)行的命令,而 ./md-read-cli 是該命令實(shí)際執(zhí)行的文件。
對(duì)于最終可執(zhí)行的命令行工具,Node 項(xiàng)目一般傾向置文件于 bin 目錄下,如以下 Typescript 的配置:
- {
- "bin": {
- "tsc": "./bin/tsc",
- "tsserver": "./bin/tsserver"
- },
- }
一個(gè)執(zhí)行環(huán)境
對(duì)于可直接執(zhí)行的文件,需要指明執(zhí)行環(huán)境,首行添加一行說(shuō)明:
- #!/usr/bin/env node
- // code 往下寫(xiě)
這一句話(huà)是啥子意思了?
所以這句話(huà)的意思是: 使用 node 執(zhí)行這個(gè)腳本
- // 不寫(xiě) #!/usr/bin/env node
- $ node serve .
- // 寫(xiě)上 #!/usr/bin/env node
- $ serve .
解析命令輸入
- $ node cmd.js 1 2 3
- // Output: [
- // '/usr/local/bin/node',
- // '/Users/shanyue/cmd.js',
- // '1',
- // '2',
- // '3',
- // ]
- process.argv
根據(jù)解析 process.argv 來(lái)獲取各式各樣的參數(shù)作為命令行的輸入,當(dāng)然解析參數(shù)也要參照基本規(guī)律: 格式、可選、必選、簡(jiǎn)寫(xiě)、說(shuō)明、幫助等等。命令行工具命名協(xié)議 文章中已說(shuō)的足夠詳細(xì)。
- // 一個(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.
以此衍生出了關(guān)于解析命令參數(shù)的多個(gè)庫(kù),在實(shí)際工作中就直接用吧!
使用 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)
豐富的色彩體驗(yàn)
Next 構(gòu)建輸出
目前大部分終端已支持彩色輸出,豐富的高亮色彩如同代碼高亮一樣使用戶(hù)可以快速抓住重點(diǎn)。把異常、警告、成功的信息用不同的顏色標(biāo)出,命令行工具的輸出一目了然。在現(xiàn)代構(gòu)建工具,如 Webpack 下,也大都支持彩色輸出。
以下是在命令行工具中常用的兩個(gè)色彩庫(kù),支持多種多樣色彩的輸出。
以下是 chalk 示例,Error 與 Warning 信息用不同的顏色表示
- const chalk = require('chalk')
- const error = chalk.bold.red
- const warning = chalk.keyword('orange')
- console.log(error('Error!'))
- console.log(warning('Warning!'))
發(fā)布與安裝
在辛苦努力寫(xiě)完一個(gè) cli 工具后,就是檢驗(yàn)成果的時(shí)候。發(fā)布到 npm 倉(cāng)庫(kù),可使所有人使用你的命令行工具,這也是最重要的一步
- # 發(fā)布之前需要 npm login,登錄到 npm registory
- $ npm publish
發(fā)版成功后全局下載命令行工具,開(kāi)始使用,示例用它抓取下我的博客首頁(yè)
- $ 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)維中遇到問(wèn)題的一些文章總結(jié)。以后也會(huì)做系列文章進(jìn)行輸出,如前端高級(jí)進(jìn)階系列,個(gè)人服務(wù)器指南系列。個(gè)人微信 shanyue94,歡迎添加交流
- ## [#](#名字由來(lái)) 名字由來(lái)
總結(jié)
本篇文章由淺至深講解了以下幾方面的內(nèi)容:
并根據(jù)實(shí)踐,開(kāi)發(fā)了一個(gè)從 URL 中讀取 Markdown 的小工具: markdown-read,歡迎 Star、下載及使用。
另外,我基于此命令行做了一個(gè) Web 版,歡迎來(lái)體驗(yàn): https://devtool.tech/html-md
本文轉(zhuǎn)載自微信公眾號(hào)「全棧成長(zhǎng)之路」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系全棧成長(zhǎng)之路公眾號(hào)。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流