服务器代码中的 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 & The Hot Module Replacement热模块替换原理解析