2017-03-17 114 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

相关问题