服务器代码中的 Webpack 热模块替换

Posted

技术标签:

【中文标题】服务器代码中的 Webpack 热模块替换【英文标题】:Webpack hot module replacement in server code 【发布时间】:2016-03-10 04:18:21 【问题描述】:

到目前为止,我看到的所有 webpack 示例都涉及客户端热模块替换,例如:this 和 this。

根据 webpack 文档,可以使用 webpack-dev-server 或中间件(webpack-dev-webpack-dev-middleware 和 webpack-hot-middleware,以及配置中的 webpack-hot-middleware/client entry,以及集成到例如 express js) 以启用客户端代码的热模块替换

是否可以为服务器端代码启用热模块更换?该文档确实显示了example

var requestHandler = require("./handler.js");
var server = require("http").createServer();
server.on("request", requestHandler);
server.listen(8080);

// check if HMR is enabled
if(module.hot) 
    // accept update of dependency
    module.hot.accept("./handler.js", function() 
        // replace request handler of server
        server.removeListener("request", requestHandler);
        requestHandler = require("./handler.js");
        server.on("request", requestHandler);
    );

该文档的解释相当冗长。

所以问题是,如何在服务器端代码中实现热模块替换而不重新启动服务器? (目前,我有 nodemon 监视服务器端代码以在文件更改时重新启动服务器)

【问题讨论】:

你找到答案了吗?我正在为完全相同的事情而苦苦挣扎,我会为一个简单的运行示例而死有一些解释。 Webpack 对我来说仍然是纯粹的魔法...... 我终于在github.com/aunz/mwb/tree/master/examples/basicApp 创建了我自己的示例。看看吧。 这看起来不错,谢谢! @Green,你能分享任何链接或文章吗?查看该工具,我可以部分了解正在发生的事情。真的很感激。 @VladNicula,1) 服务器代码在 this line 中被监视,并在 this line 中作为分叉子运行。 2) 在代码更改时,会向this line 中的服务器发送信号“hmr”。 'hrm' 信号通过“受启发的”原始signal.js 处理,该原始signal.js 执行热更新或重新加载。 【参考方案1】:

与 Webpack 捆绑的热重载服务器中间件实际上比热重载客户端捆绑包容易得多,原因有两个:

    您不必处理服务器/客户端通信。 中间件几乎总是无状态的,因此您无需担心状态保存。

这意味着您可以忽略与客户端热模块重新加载相关的所有移动部分,例如 WebSockets 以及通过module.hot.accept / module.hot.dispose 教您的代码自我更新。

这是一个例子:

// ./src/middleware.js
module.exports = (req, res) => 
    res.send('Hello World');
;
// webpack.config.js
const path = require('path');

module.exports = 
    target: 'node',
    entry: './src/middleware.js',
    output: 
        path: path.join(__dirname, './dist'),
        filename: 'middleware.js',
        libraryTarget: 'commonjs2'
    
;
// ./src/index.js
const express = require('express');
const config = require('webpack.config.js');

const app = express();
const queue = [];
let latestMiddleware;

webpack(config).watch(() => 
    // re-require new middleware
    delete require.cache[require.resolve('./dist/middleware.js')]
    latestMiddleware = require('./dist/middleware.js');
    // pass buffered requests to latestMiddleware
    while (queue.length) latestMiddleware.apply(void 0, queue.shift());
);

app.use((req, res, next) => 
    if (latestMiddleware) 
        latestMiddleware(req, res, next);
        return;
    
    queue.push([req, res, next]);
);

app.listen(6060);

如您所见,无需担心状态意味着latestMiddleware 可以简单地引用新的捆绑中间件,而无需编写自定义逻辑来更新依赖图中的其他模块。

顺便说一句,这与 webpack-hot-server-middleware 使用的技术完全相同,唯一的区别是 webpack-hot-server-middleware 更适合在服务器上热重载通用应用程序。

【讨论】:

【参考方案2】:

这是一个很好的起点,https://github.com/jlongster/backend-with-webpack。

【讨论】:

由于某些原因,我无法让示例运行 发布的代码库附有 3 篇关于作者选择该特定补丁的原因的系列文章。最相关的是他谈到服务器端 webpack 捆绑的第二部分:jlongster.com/Backend-Apps-with-Webpack--Part-II。但是,他的方法不支持在服务器上进行热重新加载。正如他在文章中所解释的那样,他总是在更改时重新启动,并且您可以在他的 gulpfile 的源代码中看到:github.com/jlongster/backend-with-webpack/blob/master/… 使用 gulp && webpack?那是懒惰的解决方案...不,谢谢。 :)

以上是关于服务器代码中的 Webpack 热模块替换的主要内容,如果未能解决你的问题,请参考以下文章

webpack-- 模块热替换

Webpack & The Hot Module Replacement热模块替换原理解析

本地 ES 模块(浏览器或 Node.js)的热模块替换*没有* Webpack?没有构建工具

webpack 热更新

webpack优化配置

webpack优化配置