1. 程式人生 > 程式設計 >element用指令碼自動化構建新元件的實現示例

element用指令碼自動化構建新元件的實現示例

目錄
  • 背景
  • element-ui的自動化構建是怎麼www.cppcns.com做的
    • makefile
    • new.
    • file-save
  • 引用資原始檔的修改
    • fs.createWriteStream
  • 總結

    背景

    在公司的專案中,每次碰到新需求的時候,你是不是都還在用新建頁面 => 往頁面中新增內容,如模板 => 新增路由。難道不覺得麻煩嗎?如果是的話,不妨試試自動化構建吧,太香了~

    element-ui的自動化構建是怎麼做的

    在開源專案中,特別是UI庫的開發,有太多人協同,每個人的code習慣也都不一樣。並且UI庫中每個元件都還會涉及到多語言、單元測試、路由、元件的readme.md文件等檔案。所以如果每次都慢慢去建立這些則太麻煩了,並且多人修改公共檔案如路由檔案會產生非常多的衝突。所以在開源專案中都會有非常多的,去自動化生成某些檔案。

    makefile

    在elemrAFqgwQent-ui專案根目錄有個makefile檔案,每條命令的作用都在註釋中。windows使用者要使用make命令執行指令碼得下載。mac使用者不需要。

    @# 預設的#註釋會在日誌中輸出,@#則不會
    @# .PHONY的作用: 在下方的指令碼命令中忽略檢查是否與dist、test目錄衝突,也就是說無論如何都會去執行命令
    .PHONY: dist test
    
    @# 執行make命令時,預設執行help指令碼
    default: help
    
    @# 執行`make build-theme`就是執行`npm run build:theme`指令碼,
    @# : 冒號前面為執行的命令,冒號後面第二行第一個應該為一個tab,tab之後跟指令碼命令
    @# 也就是說下面的為 'tab+npm npm build: theme'
    # build all theme
    @# 上面的build theme註釋可以檢視下方的截圖,會在日誌中輸出
    build-theme: 
     npm run build:theme
    install:
     npm install
    dev:
     npm run dev
    @# $()為使用函式
    @# $@ 為當前命令本身比如 'make new',$@ 就是 new
    @# MAKECMDGOALS 特殊變數,該變數記錄了命令列引數指定的目標列表,也就是說使用這個變數,我們可以得到命令列的引數
    @# 比如我們在建立新元件時,使用指令碼`make new wailen` MAKECMDGOALS 就等於 wailen
    @# filter-out 反過濾函式,過濾掉 $(MAKECMDGOALS) 中所有含有 $@ 的內容
    @# 結合new.js的內容,下方指令碼的意思也就是建立新組建,傳入元件名稱,元件名稱不得為new,如果元件名稱取為new,可以檢視下方截圖
    new:
     node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS))
    @# 省略了一些指令碼,感興趣的可以自行檢視原始碼
    help:
     @echo "   \033[35mmake\033[0m \033[1m命令使用說明\033[0m"
     @echo "   \033[35mmake install\033[0m\t\033[0m\t\033[0m\t\033[0m\t---  安裝依賴"
     @echo "   \033[35mmake new <component-name> [中文名]\033[0m\t---  建立新元件 package. 例如 'make new button 按鈕'"
     @echo "   \033[35mmake dev\033[0m\t\033[0m\t\033[0m\t\033[0m\t---  開發模式"
     @echo "   \033[35mmake dist\033[0m\t\033[0m\t\033[0m\t\033[0m\t---  編譯專案,生成目標檔案"
     @echo "   \033[35mmake deploy\033[0m\t\033[0m\t\033[0m\t\033[0m\t---  部署 demo"
     @echo "   \033[35mmake pub\033[0m\t\033[0m\t\033[0m\t\033[0m\t---  釋出到 npm 上"
     @echo "   \033[35mmake new-lang <lang>\033[0m\t\033[0m\t\033[0m\t---  為新增新語言. 例如 'make new-lang fr'"

    # 註釋輸出

    element用指令碼自動化構建新元件的實現示例

    過濾new關鍵字,當傳入引數為new時,過濾掉

    element用指令碼自動化構建新元件的實現示例

    當然,如果不想使用make直接執行node指令碼即可,比如make new 元件名 等同於 node build/bin/new.js 元件名

    new.js

    new.js為自動化的核心檔案。我們先思考一下,建立元件檔案無非就是兩個步驟

    • 建立檔案
    • 新增內容

    file-save

    主要是通過file-save這個包建立檔案並新增內容。先來看看api

    const fileSave = require('file-save');
    const content = "const fs = require('fs');"
    const callback = () => { console.log('指令碼執行') }
    fileSave('檔案路徑')
       .write('檔案內容比如上面的content','utf8',callback) // 內容寫入成功會觸發回撥
       .write('繼續新增content','utf8')
       .end('\n') // 檔案操作結束,以空白行結束
    

    如此便會生成如下檔案

    element用指令碼自動化構建新元件的實現示例

    更多的文件可以檢視file-save

    element-ui中就是先通過一個Files陣列物件管理了需要建立的filename以及code content。

    element用指令碼自動化構建新元件的實現示例

    這樣直接迴圈Files就能建立對應的檔案了。

    // 建立 package
    // 元件生成的目錄
    const PackagePath = path.resolve(__dirname,'../../packages',componentname);
    Files.forEach(file => {
      fileSave(path.join(PackagePath,file.filename))
        .write(file.content,'utf8')
        .end('\n');
    });
    

    引用資原始檔的修改

    另外,一般建立了元件還需要修改相應需要引用元件的地方,比如路由配置檔案等。我們同樣可以通過file-save去新增對應的路由。本身file-save會覆蓋之前檔案中的內容,也就是刪除過後重新再次生成。所以如果是在原有基礎上做增的操作的話,就需要獲取到原有檔案的內容,再在此基礎上拼接新內容。我們可以這樣做:

    const fileSave = require('file-save');
    const fs = require('fs');
    
    const content = `const fileSave = require('file-save'); `
    const oldCode = fs.readFileSync('./demo.js')
    fileSave('demo.js')
      .write(oldCode+content,'utf8')
      .end('\n')
    
    

    也就是通過fs模組讀取到檔案的舊內容,再拼接即可。element-ui是這麼做的:

    element用指令碼自動化構建新元件的實現示例

    fs.createWriteStream

    file-save原理就是通過fs.createWriteStream這個api做了一層封裝。
    簡單說下使用

    const fs = require('fs')
    
    //建立可寫流 fs.WriteStream 類的物件,繼承自 <stream.Writable>
    const writer = fs.createWriteStream('createStream.js',{ // 查詢該檔案,沒有則建立
        //預設值為w, 通過呼叫writer.write方法寫入資料的時候,會直接覆蓋檔案所有的內容,
        // 即會把檔案之前的內容全部再刪除,寫入新的資料
        flags: 'w'
    })
    
    
    //寫入資料到流
    writer.write('這個檔案的新內容')

    file-save的原始碼內容可以檢視下面的虛擬碼。

    const savefs = {}
    savefs._create_dir = function (fp,opts) {
    http://www.cppcns.com  mkdirp.sync(fp,opts);
    }
    savefs.wstream = function (file) {
      var ws = fs.createWriteStream(file);
      this.writer = ws;
      return this;
    }
    savefs.write = function(chunk,encoding,cb) {
      ...
    }
    
    savefs.end = function(chunk,cb) {
      ...
    }
    
    savefs.finish = function(cb) {
      ...
    }
    
    savefs.error = function(cb) {
      ...
    }
    export { savefs }
    
    

    當然,其實我們可以直接使用node的fs.writeFile這個API去建立檔案,

    fs.writeFile('檔案路徑','要寫入的內容',['編碼'],'回撥函式');
    

    可以發現引數跟file-save一樣

    總結

    歸根到底,自動化建立元件無非就是兩個核心建立檔案 新增內容。通過file-save這個包就可以實現這兩個操作,然後我們再結合自身的業務,配置好生成檔案的路徑與內容,以及做好某些公共檔案對新檔案資源引用的修改即可。有沒有覺得node寫指令碼,比寫後端有意思多了~

    到此這篇關於element用指令碼自動化構建新元件的實現示例的文章就介紹到這了,更多相關element指令碼自動化構建新元件內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!