Webpack2 Hot Module 重新加载 Express.js 通用 React 应用程序

Posted

技术标签:

【中文标题】Webpack2 Hot Module 重新加载 Express.js 通用 React 应用程序【英文标题】:Webpack2 Hot Module Reloading a Express.js Universal React App 【发布时间】:2017-06-06 09:58:32 【问题描述】:

通用应用程序的 webpack 配置通常是一个配置对象数组,例如:

module.exports = [
    
        name: 'client',
        entry: 
            app: [...require("./loaders").hotLoaders, "./src/frontend/client"],
            libs: [
                'react', 'react-dom'
            ]
        ,
        output: 
        path: path.join(__dirname, "../../www"),
        filename: "js/[name].bundle.js"
        , 
     ...
    ,
    
        name: 'server',
        target: 'node',
        entry: 
            server: ["./src/universal/server"],
            express: ["./src/universal/express"]
        ,
        output: 
        path: path.join(__dirname, "../../www"),
        filename: "js/[name].bundle.js"
          
        ...   
    ];

运行webpack --config build/webpack/prod.js 后,我可以在生产环境中执行以下操作,只需像node www/express.bundle.js 一样运行 server.express 块的输出。

//  src/universal/express.tsx 
import SERVER from "./server"
const express = require("express");
const app = express();
app.use(express.static('www'));
app.use(require("morgan")('combined'));
app.use(SERVER);
app.listen(3000);

对于开发,我可以node hot.js 让 HMR 运行良好。

// hot.js
const app = require("express")();
const compiler = require('webpack')(require('./build/webpack/prod.js'));
app.use(require('webpack-dev-middleware')(compiler);
app.use(require('webpack-hot-middleware')(compiler.compilers.find(compiler => compiler.name === 'client')));
app.use(require("morgan")('combined'));
app.use(require("./www/server.bundle").default);
app.listen(3000);

HMR 像这样工作得非常快。但是,一旦我开始编辑我的文件,react 就会向我显示有关 React attempted to reuse markup 的警告。当代码更改时,hmr 会发挥它的魔力,但是即使进行了硬刷新,服务器也会继续发送旧标记,因为我很难需要像 let SERVER = require("./www/server.bundle").default; 这样的捆绑文件,也许 webpack-dev-server 可以处理这个问题,但是我该如何设置它一组 webpack 配置?

我也想过把 hot.js 做成一个块,但是它调用require('./build/webpack/prod.js') 又调用require('webpack') 很多,这让 webpack 生气并且没有编译任何东西。

【问题讨论】:

你能分享你的 package.json 和 webpackconfig 我正在寻找相同的 github.com/cescoferraro/spotify@AnilGupta 【参考方案1】:

您可能对旨在解决这个问题的webpack-hot-server-middleware 感兴趣。

您需要做的就是将硬编码的require('./www/server.bundle').default 替换为webpack-hot-server-middleware,例如

const app = require("express")();
const compiler = require('webpack')(require('./build/webpack/prod.js'));
app.use(require('webpack-dev-middleware')(compiler);
app.use(require('webpack-hot-middleware')(compiler.compilers.find(compiler => compiler.name === 'client')));
app.use(require("morgan")('combined'));
app.use(require('webpack-hot-server-middleware')(compiler,  chunkName: 'server' );
app.listen(3000);

Webpack Hot Server Middleware 将确保每个请求都被传递到server.bundle.js 的最新编译,因此您在开发过程中不再需要重新启动服务器。

此外,它还具有与客户端捆绑共享相同的 Webpack 缓存以加快构建速度的额外好处。

【讨论】:

以上是关于Webpack2 Hot Module 重新加载 Express.js 通用 React 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

webpack学习之—— 模块热替换(Hot Module Replacement)

webpack 2 热重载不重新渲染

webpack2的配置属性说明entry,output,state,plugins,node,module,context

webpack的Hot Module Replacement运行机制

react-hot-loader 和 webpack-dev-server 不会重新加载更改

Webpack / react hot reload重新加载整个页面?