服务器端的Webpack热模块替换

5
到目前为止,我看过的所有webpack示例都涉及客户端热模块替换,例如:这个这个
根据webpack文档,可以使用webpack-dev-server或中间件(webpack-dev-webpack-dev-middleware和webpack-hot-middleware,以及在配置输入中集成的webpack-hot-middleware/client,例如express js)来启用客户端代码的热模块替换,但是能否启用服务器端代码的热模块替换呢?文档确实展示了一个示例
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对我来说仍然是纯粹的魔法... - Stijn de Witt
我终于在https://github.com/aunz/mwb/tree/master/examples/basicApp上创建了自己的示例。看一下吧。 - Green
这看起来不错,谢谢! - Stijn de Witt
@Green,你能分享一些你建立这个工具时受到启发的链接或文章吗?浏览了一下这个工具,我部分地理解了正在发生的事情。真的非常感激。 - Vlad Nicula
1
@VladNicula,1)服务器代码在此行中被监视,并在此行中作为分叉子进程运行。2)当代码更改时,在此行中向服务器发送“hmr”信号。“hrm”信号通过“inspired”原始signal.js进行处理,它可以执行热更新或重新加载。 - Green
2个回答

2

与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更加专注于在服务器上热重载通用应用程序。

-1

由于某些原因,我无法使示例运行。 - Green
发布的代码库附带了3篇关于作者选择该特定补丁的原因的文章。其中最相关的是第二部分,他在其中谈到了服务器端的webpack打包:http://jlongster.com/Backend-Apps-with-Webpack--Part-II。然而,他的方法不支持服务器上的热重载。正如他在文章中解释的那样,并且正如您可以在他的gulpfile的源代码中看到的那样,他总是在更改时重新启动:https://github.com/jlongster/backend-with-webpack/blob/master/gulpfile.js#L143 - Vlad Nicula
使用gulp和webpack?那是懒惰的解决方案...不用了,谢谢。 :) - Michal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接