Node.js Web應用程式碼熱更新

qwer ?發表於2019-10-21

?實現思路:將啟動檔案中的 router、proxy 檔案分離出主檔案,對分離出去的檔案實現熱更新。關鍵問題點:

  • 如何更新模組程式碼
  • 如何使用新模組處理請求
  • 如何釋放老模組的資源

如何更新模組程式碼

引入 chokidar 當監聽檔案修改時,清除該模組快取,delete require.cache[path]

如何使用新模組處理請求

使用koa框架,app.use 操作會儲存舊的 router.js 模組,因此模組更新了,請求依然會使用老模組

// 利用閉包的特性獲取最新的router物件,避免app.use快取router物件
app.use((ctx, next) => router.routes()(ctx, next)).use(router.allowedMethods())

// 監聽檔案修改重新載入程式碼
const watcher = chokidar.watch(path.resolve(__dirname, '../www'), { ignored: /index\.js/ })
 watcher.on('ready', () => {
   logger.info(`will watching at '${path.resolve(__dirname, '../www')}`)
   watcher.on('all', (event, file) => {
     logger.info(`server-side hot-reload due to: ${file}`)
     Object.keys(require.cache).forEach((id) => {
       if (/\/www\//.test(id)) {
         cleanCache(id)
         try {
           if (file.endsWith('router.js')) {
             router = require('./router')
           }
           if (file.endsWith('proxies.js')) {
             proxies = require('./proxies')
           }
         } catch (ex) {
           console.error(`module ${file} update failed`)
         }
       }
     })
   })
 })

function cleanCache (module) {
   var path = require.resolve(module);
   delete require.cache[path];
}
複製程式碼

如何釋放老模組的資源

讓老模組的程式碼更新後,確保沒有物件保持了模組的引用 ,Node.js 會自動為所有模組新增一個引用

function cleanCache(modulePath) {
    var module = require.cache[modulePath];
    // remove reference in module.parent
    if (module.parent) {
        module.parent.children.splice(module.parent.children.indexOf(module), 1);
    }
    require.cache[modulePath] = null;
}
複製程式碼

解決了 koa 熱更新問題。


附上github: github.com/Jarryxin/mp…


參考: fex.baidu.com/blog/2015/0…

相關文章