前言
之前也是從grunt/gulp/fis/過來的,到現在的webpack,中間有些問題沒怎麼細想,比如明明是構建工具為什麼除錯總是要開啟一個http服務之類的,現在就來簡單梳理下思路
最原始的構建工具無非是這樣:
-
改動了某個資原始檔, 要手動執行構建命令才能重新構建,
-
重新構建的時候構建工具將所有資原始檔重新構建一次,再合併打包.
-
你要手動重新整理頁面才能載入到到最新的構建完成的資原始檔
而我們希望構建工具最好是這樣:
-
你改動了某個資原始檔,構建工具能夠監聽到這個變化,自動進行重新構建
-
構建工具重新構建的時候並不會將所有的資原始檔全部構建, 而是將
變化了的
資原始檔重新構建,再將這個變化了的
資原始檔和其他的資原始檔合併打包 -
構建完成之後能夠自動重新整理你的除錯頁面(當然如果能類似ajax無重新整理載入就更好了)
-
核心功能輕量,通過plugin來擴充其他功能,比如編譯coffee/typescript/tpl/sass等
實現原理
資原始檔修改自動編譯
監聽資源的修改實現自動編譯是構建工具要實現的基本功能,其原理是
node有api能夠可以監聽單個資原始檔的狀態(fs.watch),當資原始檔發生變化,能夠觸發回撥通知node, 這也是許多基於node的構建工具實現核心. 當然強大的node社群還出了監聽資料夾的node模組比如Chokidar
按需構建資原始檔
-
構建工具監聽到了某個資原始檔的變化,重新構建一遍這個資原始檔,然後在最後打包的階段和其他沒有變化的之前已經構建好的資原始檔合在一起重新打包成aio(
all in one
) -
構建工具監聽到了某個資原始檔的變化,重新構建一遍這個資原始檔,然後在之前構建的aio中抽離出這個資原始檔變化前的邏輯,填入變化後的邏輯, 連一塊打包都省了,不過實現起來邏輯比較複雜.
頁面自動載入新資源以方便除錯
要實現這種功能,一般要在本機建立一個簡單的http server,構建工具構建完成之後將檔案整個放置在server目錄.
並且在開發環境(dev)中,構建工具構建出來的最終的頁面檔案除了你的業務程式碼,一般還會引入一段socket
的相關程式碼,通過socket使得client能夠一直和server保持通訊.比如你構建完成之後,通過127.0.0.1:port/index.html除錯頁面,你這個index.html中嵌入了了socket的程式碼(當然,生產環境(prod)不會把socket的功能打包進去的)
有了socket使得服務端和客戶端保持通訊連線,伺服器推動客戶端重新整理就很容易實現了. 處理方式有兩種,同步重新整理
和非同步熱載入
-
如果伺服器資源發生了變化,伺服器會通過socket來向客戶端傳送指令,客戶端socket捕獲到這條指令,就重新整理頁面來過載新的資源.
-
如果伺服器發生了變化,伺服器會通過socket來向客戶端傳送指令,客戶端socket捕獲到這條指令,非同步向伺服器拉去新的資源,來實現無重新整理非同步過載.
通過plugin來擴充其他功能
絕大多數構建工具都是通過外掛擴充的,就不說了