2017-03-17 67 views
0

這是一個邊緣案例,但它會有助於知道。使用webpack-dev-derver在客戶端監聽熱更新事件?

使用的WebPack-dev的服務器,以保持擴展代碼最新開發的延伸,這將是聽取有用的「webpackHotUpdate」

的Chrome擴展程序與內容的腳本經常有雙方的方程:

  1. 背景
  2. 注入的內容腳本

使用的WebPack-DEV-服務器HMR背景PA ge保持同步就好了。但是,內容腳本需要重新加載擴展才能反映更改。我可以通過監聽來自hotEmmiter的「webpackHotUpdate」事件並請求重新加載來彌補這一點。目前我的工作方式非常糟糕,非常不可靠。

var hotEmitter = __webpack_require__(XX) 

hotEmitter.on('webpackHotUpdate', function() { 
    console.log('Reloading Extension') 
    chrome.runtime.reload() 
}) 

XX只是表示當前分配給發射器的編號。正如你可以想象,只要構建發生變化,它就會發生變化,所以這是對概念的一種非常暫時的證明。

我想我可以建立自己插座,但似乎有點小題大做,因爲事件已經被轉移,我只是想聽聽。

我剛剛越來越熟悉的WebPack生態系統,因此任何指導是非常讚賞。

回答

1

好吧!

我工作了這一點,通過尋找在這裏:

https://github.com/facebookincubator/create-react-app/blob/master/packages/react-dev-utils/webpackHotDevClient.js

許多感謝創造反應的應用程序內的團隊爲他們明智地使用意見。

我創造了這個簡化版本,專爲處理延期開發的重載條件。

var SockJS = require('sockjs-client') 
var url = require('url') 

// Connect to WebpackDevServer via a socket. 
var connection = new SockJS(
    url.format({ 
     // Default values - Updated to your own 
     protocol: 'http', 
     hostname: 'localhost', 
     port: '3000', 
     // Hardcoded in WebpackDevServer 
     pathname: '/sockjs-node', 
    }) 
) 

var isFirstCompilation = true 
var mostRecentCompilationHash = null 

connection.onmessage = function(e) { 
    var message = JSON.parse(e.data) 
    switch (message.type) { 
     case 'hash': 
      handleAvailableHash(message.data) 
      break 
     case 'still-ok': 
     case 'ok': 
     case 'content-changed': 
      handleSuccess() 
      break 
     default: 
     // Do nothing. 
    } 
} 

// Is there a newer version of this code available? 
function isUpdateAvailable() { 
    /* globals __webpack_hash__ */ 
    // __webpack_hash__ is the hash of the current compilation. 
    // It's a global variable injected by Webpack. 
    return mostRecentCompilationHash !== __webpack_hash__ 
} 

function handleAvailableHash(data){ 
    mostRecentCompilationHash = data 
} 

function handleSuccess() { 
    var isHotUpdate  = !isFirstCompilation 
    isFirstCompilation = false 

    if (isHotUpdate) { handleUpdates() } 
} 

function handleUpdates() { 
    if (!isUpdateAvailable()) return 
    console.log('%c Reloading Extension', 'color: #FF00FF') 
    chrome.runtime.reload() 
} 

當你準備使用它(只在開發過程中),你可以簡單地把它添加到您的background.js切入點

module.exports = { 
    entry: { 
     background: [ 
      path.resolve(__dirname, 'reloader.js'), 
      path.resolve(__dirname, 'background.js') 
     ] 
    } 
} 




對於實際掛鉤到事件發射器是最初被問到的,因爲該文件導出了使用的EventEmitter的一個實例,所以您可以從webpack/hot/emitter中只需要它。

if(module.hot) { 
    var lastHash 

    var upToDate = function upToDate() { 
     return lastHash.indexOf(__webpack_hash__) >= 0 
    } 

    var clientEmitter = require('webpack/hot/emitter') 

    clientEmitter.on('webpackHotUpdate', function(currentHash) { 
     lastHash = currentHash 
     if(upToDate()) return 

     console.log('%c Reloading Extension', 'color: #FF00FF') 
     chrome.runtime.reload() 
    }) 
} 

這僅僅是一個精簡版,直接從源:

https://github.com/webpack/webpack/blob/master/hot/dev-server.js

+0

聽起來很酷,我將嘗試了這一點。如果我理解正確,你的答案中的源代碼的最後一部分(if(module.hot){)開頭只是一個替代解決方案。 您可以分享關於如何從webpack dev服務器運行擴展的任何提示,因爲看起來localhost上的捆綁js文件會導致manifest.json中的內容腳本無效? – Steve06