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

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

根据 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 执行热更新或重新加载。

标签: webpack webpack-dev-server


【解决方案1】:

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

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

这意味着您可以忽略与客户端热模块重新加载相关的所有移动部分,例如 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?那是懒惰的解决方案...不,谢谢。 :)
    猜你喜欢
    • 2018-09-22
    • 2016-04-05
    • 1970-01-01
    • 2017-06-20
    • 2017-02-27
    • 1970-01-01
    • 2017-06-28
    • 2017-05-10
    • 2022-07-01
    相关资源
    最近更新 更多