從事 Web 開發的程序員,對於先後端分離模式多半不陌生,這也是目前主流的 Web 開發模式,具體關於先後端分離的模式能夠參看文章《你不得不瞭解的先後端分離原理!》,在這裏寫者不進行說明。html
好了,讓咱們進入主題 —— Node.js 先後端分離開發新思路
在進入新思路以前,咱們現須要瞭解「老思路」是什麼?(注意:後面的案例都是以全棧工程師爲例,即先後端代碼在一塊兒)前端
以一種具體情景爲例:小牛是一名全棧工程師,喜歡前端後端全乾,前端使用目前主流的 Webpack + React 全家桶(或 Vue 全家桶),後端使用 express(或 Koa),小牛在同時開發先後端過程當中,開啓兩個進程(先後端各一個),同時使用 nodemon 熱重啓後臺服務,使用 Webpack Proxy 轉發實現跨域請求,而後哼哧哼哧開發。
如例子:一個先後端分離的簡單案例node
Process 1 Process 2 ___________ ____________________ | | Proxy | | | | FrontEnd | <----> | Nodemon | BackEnd | | | | | (cp 1) | ------------- ----------------------
如上示意,該模式啓動須要啓動兩個進程(前端 和 Nodemon),其中 BackEnd 程序做爲子進程掛載在 Nodemon 進程,並且前端和 Nodemon 進程經過 Proxy 轉發實現通訊。webpack
乍看一下這樣挺美好的,可是這種模式的缺陷也很容易暴露出來git
那麼對於上述的問題,須要介紹一下咱們今天的主角!程序員
依舊是小牛的例子,大牛一樣使用小牛相同的先後端技術棧,但不一樣的是,大牛不使用 Nodemon 實現後端程序的熱重啓,而是使用相似 Webpack HMR(Hot Module Replacement) 的思路,熱更新 Node.js 中的 module,具體實現使用 hot-module-require。github
原理圖以下,先後端在一個進程(同一個端口)中,經過 Fs Watcher 熱替換更新的 Module,而不是全量重啓。web
Process _________________________ | | File Watcher | | Frontend | + | | | Backend | ---------------------------
其中核心的 Node.js 端 HMR 實現思路以下算法
首先咱們來看看一個程序的依賴圖關係express
index.js
爲程序入口,能夠經過靜態代碼分析,獲得 index.js
的直接依賴 express/index.js
和 lib/middleware.js
,而後遞歸地進行,依次獲得一個完整的依賴圖,算法具體實現參看 detect-dep。某個時候,lib/to-array.js
文件發生改動!
delete require.caches[modulePath]
)其中這一步須要注意環狀依賴的處理,須要保證一條依賴路徑,不進行重複的依賴更新。
如 lib/to-array.js
,存在兩條路徑:lib/to-array.js -> lib/middleware.js -> index/js
和 lib/to-array.js -> lib/express-utils.js -> lib/middleware.js -> index/js
以上算法的具體實現參看 hot-module-require,
具體的應用代碼能夠參看這裏
相比與傳統模式,新思路的優勢十分突出。
用一個具體的場景對比舉例,如後端使用內存存儲用戶 session 數據。如使用傳統方式開發,則每一次更新後臺代碼,都會丟失內存中的用戶數據,因此每次都須要從新進行登陸;可是在新方式,只須要不修改用戶登陸模塊代碼,則不會重置用戶 session 數據,即不需從新登陸。
Backend 入口 / \ - - 登陸 --> Common <-- 某業務邏輯
如上簡易模塊依賴圖,A -> B 表示 A 依賴 B,因此上圖中,Backend 入口直接依賴 「登陸」和「某業務邏輯」,間接依賴「Common」;這時候咱們只有在修改了「登陸」或「Common」的代碼,纔會觸發登陸模塊的熱更新。
可是新方法也不是完好陷
使用 Node.js HMR 能夠實現各類各樣的熱更新體驗,如熱更新 proxy,熱更新 mock 數據,熱更新配置文件...,很是 Cool!