Node.js 新手的 cli 工具開發(fā)初體驗(yàn) - 項(xiàng)目目錄管理工具 yuki

技術(shù)的學(xué)習(xí)一定要輔以代碼的實(shí)踐乐纸,菜鳥程序員撲在輪子上要像饑餓的人撲在面包上衬廷。
——沃茲基碩德

受到掘金上看到的 yddict:一個命令行查單詞的工具 的啟發(fā),原來摸一個 Node.js 的 demo 不一定非要寫一個服務(wù)器汽绢。恰逢最近開始看《算法(第4版)》吗跋,把練習(xí)代碼和筆記傳到 github 上時需要在 README.md 里放一份帶鏈接的目錄,方便在線跳轉(zhuǎn)查閱。兩者綜合跌宛,就有了開發(fā)一個能夠?qū)㈨?xiàng)目內(nèi)文件結(jié)構(gòu)自動映射并生成為 README.md 的項(xiàng)目目錄管理工具的靈感酗宋。

看上去是一個簡單的小工具,實(shí)際上花了 3 天才基本成型(當(dāng)然不是整的)疆拘。隨著思路從項(xiàng)目目錄管理到圖書管理再到書籍再到文藝社蜕猫,我決定將這個小工具命名為 yuki,蘊(yùn)含了我個人滿滿的宅趣味哎迄。

命名由來-長門大萌神

幸運(yùn)的是回右,這個日語里常見的詞竟然在 NPM 里還沒被搶用。我也因此不用為其加個后綴漱挚,直接就可以用這個名字傳上 NPM翔烁,以供使用。

這篇文章剩下來的篇幅一是介紹這個小工具的使用場景旨涝、實(shí)際用法等租漂,二是大概談一談開發(fā)過程中稍微值得一記的經(jīng)驗(yàn)。

關(guān)于 yuki

使用 Node.js 開發(fā)的項(xiàng)目目錄管理工具颊糜,能夠?qū)㈨?xiàng)目內(nèi)文件結(jié)構(gòu)自動映射并生成為 README.md

example.gif

項(xiàng)目地址

bighuang624/yuki

適用場合

當(dāng)一份 README.md 的主體內(nèi)容是項(xiàng)目目錄哩治,而你又厭倦了每次增加、修改衬鱼、刪除項(xiàng)目中文件時都要對 README 進(jìn)行維護(hù)业筏,那么不妨試試 yuki!

它可以在極短時間內(nèi)幫你生成符合要求的 README.md 文檔鸟赫。你更可以通過配置一份 yuki.config.json 來滿足你的以下需求:

  • 固定文檔標(biāo)題
  • 目錄前后增加固定內(nèi)容
  • 映射時忽略指定文件夾蒜胖、文件、擴(kuò)展名
  • 根據(jù)指定擴(kuò)展名選擇是否去掉文件名的擴(kuò)展名或加上書名號
  • 讓每個文件都帶上 Github 的鏈接以方便在線跳轉(zhuǎn)查看

你可以用 yuki 幫助你輕松維護(hù) github 上類似博客抛蚤、筆記台谢、代碼匯總等項(xiàng)目!

效果示例

我的《算法》筆記及代碼項(xiàng)目的 README.md 完全通過 yuki 生成岁经。你可以點(diǎn)擊以查看效果朋沮。

使用方法

請確認(rèn)你使用的電腦有 Node 環(huán)境,越新越好缀壤。

安裝 yuki

npm install -g yuki

進(jìn)入需要生成 README.md 的文件夾

# 請將 <dirname> 換為文件夾路徑
cd <dirname>

創(chuàng)建 yuki.config.json(可選)

touch yuki.config.json

配置 yuki.config.json(可選)

{
  // README.md的大標(biāo)題(h1)樊拓,默認(rèn)為所在文件夾名
  "title": "《算法(第4版)》筆記及代碼",
  // github庫地址,如果配置了這項(xiàng)會給每個文件加上超鏈接
  // 如果配置塘慕,請保證index填寫無誤筋夏,且所有文件名不含空格(否則鏈接無法正確表示)
  // branch默認(rèn)為master
  "repository": {
    "index": "https://github.com/bighuang624/Algorithms-notes",
    "branch": "master"
  },
  // 目錄開始的標(biāo)題等級
  // 默認(rèn)為2,即該目錄下的文件夾名等級從3開始图呢,隨層級深入遞減
  "startLevel": 2,
  // 需要忽略的目錄条篷、擴(kuò)展名和文件骗随,都以數(shù)組表示
  "ignore": {
    "dir": [".git"],
    "extname": [".json"],
    "file": [
      "yuki.config.json",
      ".gitignore",
      "README.md",
      ".DS_Store"
    ]
  },
  // 根據(jù)擴(kuò)展名選擇對展示的文件名做一些處理
  // 每個擴(kuò)展名的配置需要單獨(dú)一個對象
  // 目前支持省略擴(kuò)展名"withoutExt": true
  // 和加上書名號"withBookmark": true
  "format": [
    {
      "extname": ".md",
      "withoutExt": true,
      "withBookmark": true
    }
  ],
  // 在大標(biāo)題之后,目錄之前添加的內(nèi)容
  // 每個對象可選擇包含標(biāo)題赴叹、標(biāo)題等級和內(nèi)容
  // 其中蚊锹,標(biāo)題和標(biāo)題等級需在一個對象中一同填寫
  "prefix": [
    {
      "content": "[![](https:\//img.shields.io\/badge/%E4%BD%9C%E8%80%85-KyonHuang-7AD6FD.svg)](http:\//kyonhuang.top)"
    }, {
      "title": "目錄",
      "level": "2"
    }
  ],
  // 在README.md末尾添加的內(nèi)容
  // 和prefix相同,每個對象可選擇包含標(biāo)題稚瘾、標(biāo)題等級和內(nèi)容
  "append": [
    {
      "title": "維護(hù)",
      "level": "2",
      "content": "本文檔由 [yuki](https://github.com/bighuang624/yuki) 維護(hù)"
    }
  ]
}

因?yàn)?JSON 標(biāo)準(zhǔn)中不含注釋,請?jiān)谑褂脮r將注釋去掉姚炕。項(xiàng)目中也提供一份不帶注釋摊欠、可供修改使用的 yuki.config.json 模版。

不需要的配置選項(xiàng)請全部刪除柱宦。

創(chuàng)建 README.md

yuki

LICENSE

Apache License 2.0

開發(fā)中的那些事

Cli 命令工具開發(fā)的準(zhǔn)備工作

我們來了解一下圍繞 NPM 開發(fā)的準(zhǔn)備工作些椒。第一步自然是在文件夾下使用命令npm init生成 package.json 文件。

注冊

可以通過以下命令在 NPM 資源庫中注冊用戶:

npm adduser

之后跟著要求填寫 Username掸刊、Password免糕、Email 就 ok 了。項(xiàng)目發(fā)布前可能需要npm login一下忧侧。

版本號

NPM 使用語義版本號來管理代碼石窑。語義版本號分為 X.Y.Z 三位,分別代表主版本號蚓炬、次版本號和補(bǔ)丁版本號松逊。當(dāng)代碼變更時,版本號按以下原則更新:

  • 如果只是修復(fù) bug肯夏,需要更新 Z 位经宏。
  • 如果是新增了功能,但是向下兼容驯击,需要更新 Y 位烁兰。
  • 如果有大變動,向下不兼容徊都,需要更新 X 位沪斟。

當(dāng)然我這個小項(xiàng)目比較隨便,bug 修的多了次版本號看心情也往上升一次暇矫。

你可以用npm view <pkg> version來查看你發(fā)布到 NPM 項(xiàng)目的現(xiàn)在版本號币喧。

測試小竅門

這兩個小竅門可以節(jié)省你在一邊開發(fā)一邊測試的時間(沒發(fā)現(xiàn)之前,3 天的開發(fā)時間花在這上面的不少...)袱耽。

  • 在 package.json 所在目錄下使用npm install . -g可先在本地安裝當(dāng)前命令行程序杀餐,可用于發(fā)布前的本地測試。

  • 使用npm update <pkg> -g可以把全局安裝的對應(yīng)命令行程序更新至最新版朱巨。

編寫

想要在全局使用你編寫的 cli 工具史翘,你需要在 package.json 加一個 bin 屬性:

"bin": {
  "yuki": "./index.js"
},

yuki 換做你啟動這個程序所要在命令行輸入的命令。屬性的值是項(xiàng)目的入口文件。添加這個屬性后琼讽,在命令行執(zhí)行yuki就等同于執(zhí)行node ./index.js必峰。

發(fā)布項(xiàng)目

項(xiàng)目寫了一個版本準(zhǔn)備發(fā)布,先在 package.json 所在目錄下用npm version看一下版本號钻蹬,然后就可以 publish 了吼蚁。

cd yuki
npm version
npm publish

之后就可以通過全局安裝來使用:

npm i -g yuki

獲得程序運(yùn)行的路徑

說實(shí)話,一個我很不擅長的東西就是 API问欠,哪怕是那些非常常用的肝匆。這次我一開始就遇到了麻煩:如何獲得程序開始遍歷的“根目錄”路徑?

在查找的同時順便了解了一下獲得各種路徑的方法顺献,有以下幾種:

  • process.cwd()獲得 Node.js 進(jìn)程當(dāng)前工作的路徑(即執(zhí)行命令行時候的路徑旗国,而非代碼路徑。例如在根目錄下執(zhí)行node ./xxx/xxx/example.js注整,則process.cwd()返回的是根目錄地址)能曾;

  • __dirname: 獲得代碼存放的位置(例如運(yùn)行位于/usr/a目錄下的example.js文件:node example.js,則__dirname返回/usr/a)肿轨;

  • process.execPath: 返回返回啟動 Node.js 進(jìn)程的可執(zhí)行文件所在的絕對路徑(也就是當(dāng)前執(zhí)行的 Node 自身的路徑寿冕,例如:/usr/local/bin/node)。

根據(jù)查詢結(jié)果和實(shí)際需求椒袍,應(yīng)該使用process.cwd()(我們要求在 package.json 所在目錄下使用 yuki)蚂斤。不過實(shí)際上使用的是path.resolve()path.resolve()不含參數(shù)時槐沼,返回返回當(dāng)前工作目錄的絕對路徑曙蒸,也符合要求。

yuki 的編寫也幫助我熟悉了 Node 里的很多 API岗钩,尤其是和 path 和 fs 相關(guān)的纽窟。

先遍歷文件再深度遍歷文件夾

開發(fā)的過程中發(fā)現(xiàn)一個問題:遍歷文件夾 a 下的所有文件時,經(jīng)常先深度遍歷了其中的文件夾兼吓,導(dǎo)致文件排在這些文件夾深度遍歷的結(jié)果之后臂港,在生成的 README 中無法看出其準(zhǔn)確位置。

解決方法還比較簡單视搏,就是在每一次遞歸的遍歷方法中都建立一個隊(duì)列审孽,遍歷到文件夾先推入隊(duì)列,遍歷到文件則展示浑娜。所有文件遍歷結(jié)束后佑力,將隊(duì)列中的文件夾依次取出并遍歷。這樣既滿足了要求筋遭,也沒有對深度優(yōu)先遍歷造成影響打颤。

更好的是暴拄,JS 的數(shù)組原生支持了push方法,使得我不用再寫一個隊(duì)列的實(shí)現(xiàn)编饺。

結(jié)語

盡管只是一個微不足道的小工具乖篷,我還是很開心能夠根據(jù)自己的實(shí)際需求開發(fā)了 yuki,更開心有機(jī)會開發(fā)一個能在名字中夾私貨的項(xiàng)目(早在看到 vue 的版本名時我就一直心心念念了)透且。

如果你覺得這個小工具還不錯撕蔼,或者使用時覺得很方便、減輕了重復(fù)的工作負(fù)擔(dān)秽誊,那么不妨為 yuki 點(diǎn)一個 star鲸沮,因?yàn)槲毅裤街茉诋厴I(yè)前擁有一個自己的 100+ star 項(xiàng)目。

我覺得可以

當(dāng)然养距,我更希望這些 star 是憑借我自己的開發(fā)創(chuàng)意和技術(shù)所得到的認(rèn)可的。而我的開發(fā)經(jīng)驗(yàn)確實(shí)不太足日熬,所以如果你覺得這個工具不太好使棍厌、代碼糟糕、發(fā)現(xiàn)了 bug竖席,或是有可以增加的功能耘纱,也歡迎你開 issue 或者提交 PR 來告知我。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毕荐,一起剝皮案震驚了整個濱河市束析,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌憎亚,老刑警劉巖员寇,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異第美,居然都是意外死亡蝶锋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門什往,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扳缕,“玉大人,你說我怎么就攤上這事别威∏颍” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵省古,是天一觀的道長粥庄。 經(jīng)常有香客問我,道長豺妓,這世上最難降的妖魔是什么飒赃? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任利花,我火速辦了婚禮,結(jié)果婚禮上载佳,老公的妹妹穿的比我還像新娘炒事。我一直安慰自己,他們只是感情好蔫慧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布挠乳。 她就那樣靜靜地躺著,像睡著了一般姑躲。 火紅的嫁衣襯著肌膚如雪睡扬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天黍析,我揣著相機(jī)與錄音卖怜,去河邊找鬼。 笑死阐枣,一個胖子當(dāng)著我的面吹牛马靠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔼两,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼甩鳄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了额划?” 一聲冷哼從身側(cè)響起妙啃,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎俊戳,沒想到半個月后揖赴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抑胎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年储笑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圆恤。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡突倍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盆昙,到底是詐尸還是另有隱情羽历,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布淡喜,位于F島的核電站秕磷,受9級特大地震影響莲绰,放射性物質(zhì)發(fā)生泄漏引镊。R本人自食惡果不足惜来屠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一淋淀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧易桃,春花似錦褥琐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至造寝,卻和暖如春磕洪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诫龙。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工析显, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人签赃。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓谷异,卻偏偏與公主長得像,于是被迫代替她去往敵國和親姊舵。 傳聞我的和親對象是個殘疾皇子晰绎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容