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

标签 webpack webpack-dev-server

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

根据 webpack 文档,可以在配置 webpack-hot-middleware/client 中使用 webpack-dev-server 或中间件(webpack-dev-webpack-dev-middleware 和 webpack-hot-middleware,以及 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 捆绑的热重载服务器中间件实际上比热重载客户端捆绑要容易得多,原因有两个:

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

  • 这意味着您可以忽略与客户端热模块重新加载相关的所有移动部分,例如 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 更适合在服务器上热重载通用应用程序。

    关于服务器代码中的 Webpack 热模块替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34101783/

    相关文章:

    javascript - 如何在 webpack 中导入 jquery

    webpack-dev-server:如何获取原始文件的错误行号

    javascript - '[WDS] Disconnected!' 错误对 webpack 和 Vue.js 意味着什么?

    webpack - 如何检测 webpack-dev-server 是否正在运行?

    vue.js - 错误 : Cannot find module 'webpack-cli/bin/config-yargs'

    javascript - webpack 与 uglify 结合 sass 加载器会出错,否则工作正常

    使用 webpack 将证书文件导入为字符串

    springboot + webpack 开发服务器,重建后不会更改 localhost 捆绑文件

    javascript - 无法在带有 webpack/rollup/react 的外部库中使用 Material UI

    node.js - webpack 的 NPM 启动错误