『手撕Vue-CLI』新增幫助和版本號

BNTang發表於2024-05-18

前言

經過上一篇『手撕Vue-CLI』編碼規範檢查之後,手撕 Vue-CLI 已經進階到了程式碼規範檢查這一步,已經將基本的工程搭建好了,然後程式碼規範約束也已經加入了,並且將 nue-cli 指令繫結到了全域性當中,可以在任何地方使用了。

正文

接下來這篇文章呢,就要來實現一下大多數的命令列工具都會有的兩個功能,一個是幫助,一個是版本號。

我相信這個功能大家都很熟悉,就是在命令列中輸入 nue-cli -h 或者 nue-cli --help 就可以檢視到幫助資訊,輸入 nue-cli -v 或者 nue-cli --version 就可以檢視到版本號。

沒錯,這兩個功能是大多數的命令列工具都會有的,所以我也要來實現一下。

實現幫助 --help

首先我們來實現幫助這個功能,對於我這種菜鳥來說,首先要面臨的問題就是我該如何拿到使用者在命令列中輸入的引數。

在 Node.js 中發現可以透過 process.argv 來獲取到使用者在命令列中輸入的引數,這個引數是一個陣列,第一個是 Node.js 的路徑,第二個是當前執行的檔案路徑。

我在 bin/index.js 中列印一下 process.argv

console.log(process.argv);

上面是我在沒有輸入任何引數的情況下執行 nue-cli 的輸出結果,可以看到 process.argv 的前兩個元素是 Node.js 的路徑和當前執行的檔案路徑。

然後我在輸入 nue-cli -h 的情況下執行 nue-cli,輸出結果如下:

可以看到在輸入 nue-cli -h 的情況下,process.argv 的第三個元素是 -h

這樣就可以得出結論,使用者在命令列中輸入的引數是透過 process.argv 這個陣列來獲取的,然後我們就可以透過這個陣列來判斷使用者輸入的引數是什麼了。

然後隨著程式碼也就成為了如下程式碼塊所示的這樣子:

if (process.argv[2] === '--help') {
  // 輸出幫助文件
} else if (process.argv[2] === '--version') {
  // 輸出當前的版本號
}

commander

個人覺得這樣寫程式碼不太好,所以我這裡要給大家介紹一個庫 commander,這個庫可以幫助我們更好的處理命令列引數。

npm 地址:https://www.npmjs.com/package/commander

根據官方的介紹,可以透過 commander 來更好的處理命令列引數,所以我就來安裝一下這個庫:

npm install commander

使用方式呢其實就是看官方文件介紹,這裡我就直接給大家省略了,直接上程式碼,安裝好了是不是要使用,所以要先引入:

const { program } = require('commander');

然後呢,我們就可以透過 program 來處理命令列引數了,那麼透過 program 如何拿到使用者輸入的引數呢,官方文件中有一個 program.parse() 方法,這個方法可以解析使用者輸入的引數。

將 process.argv 傳入 program.parse() 方法中,就可以解析使用者輸入的引數了。

program.parse(process.argv);

透過如上這行程式碼就已經實現了 --help 的功能了,為什麼呢,因為 commander 會自動幫我們處理 --help 這個引數,所以我們不需要再去判斷使用者輸入的引數是不是 --help 了。

加入了這行程式碼之後,我們再次輸入 nue-cli --help,就可以看到如下的輸出結果:

是不是非常的 so easy to happy,這樣就實現了 --help 的功能了。

總結一下實現 --help 的過程,其實就一點,只需要將傳遞進來的引數直接傳遞給 program.parse() 方法就可以了,commander 會自動幫我們處理 --help 這個引數,也就實現了 --help 的功能。

實現版本號 --version

接下來來實現版本號這個功能,其實實現版本號這個功能和實現幫助這個功能是一樣的,只需要將版本號傳遞給 program.version() 方法就可以了。

首先呢,我們要引入 commander,這一步已經在上面實現 --help 的時候引入了,所以這裡就不需要再引入了。

然後呢,我們要呼叫 program.version() 方法,將版本號傳遞給這個方法就可以了。

program.version('1.0.0');

那麼兩個功能一起實現的話程式碼也就演變成了如下這樣子:

const { program } = require('commander');

program.version('1.0.0');
program.parse(process.argv);

其實呢如上這種寫法還可以改一下,program 是支援鏈式呼叫的,所以我們可以將 program.version()program.parse() 合併在一起,程式碼如下:

const { program } = require('commander');

program
  .version('1.0.0')
  .parse(process.argv);

總結一下實現版本號的過程,其實就一點,只需要將版本號傳遞給 program.version() 方法就可以了,commander 會自動幫我們處理 --version 這個引數,也就實現了 --version 的功能。

抽取版本號

上面的版本號是寫死的,那麼我們可以抽取出來,放到一個單獨的檔案中,這樣方便我們統一管理版本號。

package.json 是我們專案的配置檔案,裡面有一個 version 欄位,我們可以將這個欄位抽取出來,放到一個單獨的檔案中,然後在 bin/index.js 中引入這個檔案,這樣就可以實現版本號的統一管理了。

bin 目錄下新建一個 const.js 檔案,然後將 package.json 中的 version 欄位抽取出來,放到 const.js 檔案中,程式碼如下:

const { version } = require('../package.json');

module.exports = {
  version,
};

然後在 bin/index.js 中引入這個檔案,程式碼如下:

const { version } = require('./const');

program
  .version(version)
  .parse(process.argv);

這樣就實現了版本號的統一管理了,以後只需要修改 package.json 中的 version 欄位就可以了。

相關文章