搞一個Node Cli來提高工做效率

爲何要搞

我在1月發表過一篇:從0搭建自動版本管理的Vue組件庫,是一篇搭建組件庫的todo類型的文章,包括組件庫的搭建、配置、打包、發佈。隨着公司前端基建愈來愈完善,咱們會產出愈來愈多的像這樣的前端庫,並且類型愈來愈多:組件庫、js庫、css庫,每一個庫都須要去從零開始搞搭建配置打包發佈,這種重複勞動顯然是不合理的,畢竟懶纔是第一輩子產力,那麼有沒有解決這個問題的好法子呢?因而我想到了Node Cli,安裝更新簡單、流程統一規範、後續功能可挖掘潛力大,取代了重複勞動,讓前端組的同窗有更多的時間focus on coding,大喊真香。javascript

目標

在搞以前弄清楚目標能夠有效避免作到一半遇到:我是誰?我在哪?我在幹嗎?的問題,咱們先來看看咱們的cli須要解決哪些具體的問題,我例舉幾個我工做中遇到的問題:css

  1. 按規則壓縮構建產物:庫除了要上傳到npm之外,還須要上傳到靜態資源服務器以供一些老舊的項目直接經過標籤引入,須要按照必定的路徑規則將構建產物壓縮成zip包上傳(相似/lib/front/projectName/version/xxxx.umd.js),這樣每一個項目都要去搞一套打包前刪zip包打包完成後生成zip包的邏輯。
  2. 版本控制:從0搭建自動版本管理的Vue組件庫裏給你們介紹過在項目中使用npm version對項目進行版本控制,每一個項目都要搞一份,在複製第二份的時候我就忍不了了,得抽出來。
  3. 發佈配置:每一個項目都須要一份發佈的配置,用於給發佈平臺執行,有可能須要手動修改裏面的版本號避免發佈失敗。
  4. tag:咱們上傳靜態資源服務器時是能夠覆蓋文件的,這樣有利有弊,好處是庫的發佈效率很高,缺點是不夠安全,須要一套機制來規避風險,爲咱們自動打tag,小於等於tag版本的庫就老老實實升級布丁版本更新吧。
  5. 初始化庫、添加模版組件:每次搭建庫時都得從頭開始配置webpack、項目結構、tsconfig、lint等,雖然能夠複製現有的庫作一下修枝剪葉,但哪有cli直接生成一份香。

總結一下,咱們這個Node Cli須要解決:壓縮構建產物、自動化版本控制、拉取標準發佈配置、自動打tag、下載庫模版或者組件模版。前端

以上是我遇到的問題,同窗們最好仍是結合本身的業務場景,看看Node Cli能不能幫你幹掉一些重複性工做。vue

開搞

基礎框架搭建

Node Cli的原理是使用npm i -g cli-name安裝後把包裝到全局的node_modules中,在命令行中執行指令後系統會按照node的環境變量去執行對應腳本。java

在cli項目的package.json中加入:node

{
    ...
    "bin": {
        "mycli": "./bin/mycli.js"
    }
    ...
}
複製代碼

這樣當其餘同窗全局安裝時,就能直接使用mycli指令執行mycli.js這個腳本了。webpack

咱們本地開發時可使用npm link將項目連接到包文件夾,這樣就能方便調試,不用每次都重建。git

接下來看一下mycli.js,在文件頂部添加#!/usr/bin/env node,目的是解決不一樣的用戶node路徑不一樣的問題,讓系統動態的去查找node來執行這個腳本。web

這裏咱們要依賴一些優秀的第三方包了,這裏我選擇Commander.js,它是node.js命令行接口的完整解決方案vue-cli

#!/usr/bin/env node

const { program } = require('commander')

const { resolve } = require('path')

const res = (command) => resolve(__dirname, '../src/', command) // 讀取腳本路徑

const version = require('../package.json').version

program.version(version, '-v, --version') // 執行mycli -v 或 mycli --version的時候輸出當前版本號

program.command('init').description('init lib').action(() => { // init腳本的描述與執行
    require(res('init'))
})

program.command('build').description('build lib').action(() => { // build腳本的描述與執行
    require(res('build'))
})

program.command('release').description('release lib').action(() => { // release腳本的描述與執行
    require(res('release'))
})

program.parse(process.argv) // 處理輸出參數
複製代碼

ok,到此爲止cli的基本框架就搭好了,接下來就是豐富它的功能。

豐富功能

在功能愈來愈多以後,咱們的cli自己也可能會遇到體量龐大代碼結構複雜的問題,這時候咱們能夠將單獨的功能獨立打成npm包,由cli引入這些包,插件化方案能夠參考雲音樂前端技術團隊的文章:Node CLI 工具的插件方案探索(向大佬學習)。

上文提到的須要解決的問題裏,我將使用如下三個腳原本解決,主要說一下每一個腳本實現的思路,同窗們仍是根據業務須要本身實現腳本,想象力空間仍是比較大的。

  1. init: 下載庫模版或者組件模版
  2. build: 壓縮構建產物、自動化版本控制
  3. release: 拉取標準發佈配置、自動打tag

先推薦幾個第三方庫,能夠幫助咱們更好更快的實現功能:

功能 說明
request http模塊
inquirer 強大的用戶命令行交互工具,vue-cli也用的它
shelljs 在node腳本中執行shell命令
chalk 脫離黑白cli,給輸出加點顏色
ora 命令行的菊花圖,執行耗時操做時咱們不但願用戶覺得cli卡死了
compressing 用來壓縮的
node-emoji 給命令行加一些emoji增長一些趣味(???)

init

解決問題:下載庫模板和下載組件模板

咱們能夠把預設好的庫的模板就放在咱們cli的倉庫裏,或者放在專門的模板倉庫裏,而後經過gitlab的API去獲取下載,在使用gitlab API以前須要去帳號設置裏搞來一份private_token,調用API的時候帶上這個參數給gitlab作身份驗證,而後利用API遞歸的讀取gitlab倉庫裏的文件,對應的寫入到當前目錄下,就完成了庫模板的下載,期間能夠用ora搞點菊花圖,用node-emoji多整幾個綠色的勾勾增長一下用戶體驗。

build

解決問題:壓縮構建產物、自動化版本控制

使用inquirer跟用戶交互,能夠向用戶提問:使用哪一種npm version升級策略?打包的項目類型?庫的名稱?多入口的庫選擇入口文件?打包輸出路徑?可選的執行腳本?

在cli中咱們是能夠經過require(resolve('pathTo/package.json'))去讀取用戶的package.json的,能夠獲取用戶項目的名稱、版本等信息,這些信息能夠做爲inquirer提問的默認值,畢竟每次打包都要用戶輸入的話體驗太差了,一路回車火花帶閃電確定纔是最爽的。既然能夠獲取到用戶的package.json,那咱們就能夠作一些約定的配置,好比約定用戶的package.json裏config.cli這個對象就是專門給咱們cli讀取使用的參數對象,用戶能夠寫一些定製化的配置。

我在項目中實踐的方案是使用inquirer得到的項目信息去拼湊出vue或者webpack的打包命令(公司主要用vue),例如vue組件庫的構建,最終會執行

npx vue-cli-service build --target lib --name name --dest path
複製代碼

webpack構建會執行

webpack --output-path path
複製代碼

在基礎的構建命令之上能夠從約定的config.cli中讀取用戶的配置,例如用戶有不一樣環境打包的須要就能夠添加env參數

打包後根據用戶package.json的name、version等信息,把構建產物放進/lib/front/projectName/version/xxxx.umd.js而後用compressing壓縮成zip包

release

解決問題: 拉取標準發佈配置、自動打tag

拉取標準發佈配置和init相似,都是去下載一份標準的配置,能夠根據用戶的package.json進行一些改動再寫入。

自動打tag:我爲release指令提供了一個可選參數tag,能夠經過process.argv讀取,讀取到tag參數後,使用gitlab API爲對應分支打一個tag,後續build和release均可以先檢查這個tag版本和用戶package.json的版本,提醒用戶不要忘記升級版本。

...

cli能夠作的事情還有不少,只要想象力足夠而且業務有須要,能節省重複勞動時間,均可以集成進cli做爲cli的功能使用。

總結

本文向你們介紹了Node Cli的使用場景和基本的框架搭建,提供了幾個功能的實現思路。

主要是給出本身在公司前端基建推動過程當中遇到的問題和解決問題的方案,並非業界最佳方案,但願你們若是有更好的方案和我討論,上述的方案不必定每一個公司每一個業務都通用,想要借鑑的同窗仍是建議從公司業務出發搞一份適合本身公司的cli。

我是suhangdev,歡迎與我交流前端相關話題,若是文章對你有幫助,請點贊支持噢,謝謝!

相關文章
相關標籤/搜索