本文介绍了用 webpack-dev-derver 监听客户端的热更新事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这有点极端,但了解一下会很有帮助.

This is a bit of an edge case but it would be helpful to know.

在使用 webpack-dev-server 开发扩展以保持扩展代码最新时,听webpackHotUpdate"会很有用

When developing an extension using webpack-dev-server to keep the extension code up to date, it would be useful to listen to "webpackHotUpdate"

带有内容脚本的 Chrome 扩展程序通常有两个方面:

Chrome extensions with content scripts often have two sides to the equation:

  1. 背景
  2. 注入的内容脚本

使用带有 HMR 的 webpack-dev-server 时,后台页面保持同步就好了.但是,内容脚本需要重新加载扩展以反映更改.我可以通过监听来自 hotEmmiter 的webpackHotUpdate"事件然后请求重新加载来解决这个问题.目前,我正在以一种可怕且非常不可靠的方式进行这项工作.

When using webpack-dev-server with HMR the background page stays in sync just fine. However content scripts require a reload of the extension in order to reflect the changes. I can remedy this by listening to the "webpackHotUpdate" event from the hotEmmiter and then requesting a reload. At present I have this working in a terrible and very unreliably hacky way.

var hotEmitter = __webpack_require__(XX)

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

XX 仅表示当前分配给发射器的编号.正如您可以想象的那样,每当构建发生变化时,这种情况就会发生变化,因此这是一种非常临时的概念证明.

XX simply represents the number that is currently assigned to the emitter. As you can imagine this changed whenever the build changes so it's a very temporary proof of concept sort of thing.

我想我可以设置自己的套接字,但这似乎有点矫枉过正,因为事件已经在传输,我只是想听听.

I suppose I could set up my own socket but that seems like overkill, given the events are already being transferred and I simply want to listen.

我最近才更加熟悉 webpack 生态系统,因此非常感谢您的指导.

I am just recently getting more familiar with the webpack ecosystem so any guidance is much appreciated.

推荐答案

好的!

我通过环顾四周解决了这个问题:

I worked this out by looking around here:

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

非常感谢 create-react-app 团队明智地使用评论.

Many thanks to the create-react-app team for their judicious use of comments.

我创建了一个精简版,专门用于处理扩展开发的重新加载条件.

I created a slimmed down version of this specifically for handling the reload condition for extension development.

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 入口点

When you are ready to use it (during development only) you can simply add it to your background.js entry point

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



对于最初要求的实际挂钩到事件发射器,您可以从 webpack/hot/emitter 中要求它,因为该文件导出所使用的 EventEmitter 实例.




For actually hooking into the event emitter as was originally asked you can just require it from webpack/hot/emitter since that file exports an instance of the EventEmitter that's used.

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()
    })
}

这只是一个直接从源头开始的精简版:

This is just a stripped down version straight from the source:

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

这篇关于用 webpack-dev-derver 监听客户端的热更新事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 01:28