【问题标题】:Getting webpack hot updating to work correctly in my isomorphic web app让 webpack 热更新在我的同构 web 应用程序中正常工作
【发布时间】:2016-04-27 17:09:35
【问题描述】:

我正在创建一个带有 node/express 后端和 react 前端的 webapp。我(我认为)大部分都启动并运行了,但是让浏览器执行热刷新的最后一步并没有按预期工作。我将尝试在此处发布所有相关设置。如果您需要任何其他信息来找出我做错的地方,请告诉我:

我用node ./server/index.js启动我的应用程序

webpack.config.js var path = require('path'); var webpack = require('webpack');

let webpackConfig = {
    name: 'server',
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js',
        publicPath: '/dist/',
    },
    resolve: {
      extensions: [
        '', '.js', '.jsx', '.json'
      ]
    },
    module: {
        loaders: [
            { 
                test: /\.(js|jsx)$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                query:{
                    presets: ['es2015', 'react', 'stage-2']
                }
            },
            {
                test:  /\.json$/, 
                loader: 'json-loader'
            }
        ]
    },
    entry: [
        'webpack-hot-middleware/client',
        './app/client/client.jsx'   
    ],
    plugins: [
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: JSON.stringify('production')
            }
        }),
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ]   
};
export default webpackConfig;

index.js 只包含 'babel-register' 和 'server.js'

server/server.js 从“webpack”导入 webpack; 从 '../webpack.config' 导入 webpackConfig; 从“webpack-dev-middleware”导入 webpackDevMiddleware; 从 'webpack-hot-middleware' 导入 webpackHotMiddleware;

import express from 'express';

const app = express();
const renderPage = () => {
    return `
            <!doctype html>
            <html>
            <head>
                <title>Brewing Day</title>
                <meta charset='utf-8'>
            </head>
            <body>
                <h1>Hello from server.js!!</h1>
                <div id='root'></div>
                <script src='/dist/bundle.js'></script>
            </body>
            </html>
            `;
};

const compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
    noInfo: true,
    publicPath: webpackConfig.output.publicPath })
);
app.use(webpackHotMiddleware(compiler));

app.use((req, res, next) => {
  res.status(200).end(renderPage());
});

const server = app.listen(3005, () => {
    const host = server.address().address;
    const port = server.address().port;
    console.log(`Listening at http://${host}:${port}`);
})

export default server;

app/client/client.jsx 是 webpack 配置中的入口点:

import React from 'react';
import ReactDOM from 'react-dom';
import Application from '../components/application.jsx';

window.addEventListener('load', () => {
    ReactDOM.render(<Application />, document.getElementById('root')
    );
});

在控制台中,当我启动它时,它会列出以下行:

webpack built cc1194a11614a3ba54a3 in 730ms

当我对包含 rect 组件的 client.jsxapplication.jsx 进行更改时,我的控制台中会出现两条新行:

webpack building...
webpack built 8d340a8853d3cfe9478d in 195ms

到目前为止,一切都很好!

但是,在浏览器中,它不会更新并在控制台中给出以下警告:

[HMR] The following modules couldn't be hot updated: (Full reload needed)
This is usually because the modules which have changed (and their parents) do not know how to hot reload themselves. See http://webpack.github.io/docs/hot-module-replacement-with-webpack.html for more details.
[HMR]  - ./app/components/application.jsx

我尝试将module.hot.accept() 随机添加到application.jsx。这消除了警告,但如果不按 F5 并重新加载浏览器,仍然没有更新。

知道我在这里缺少什么吗?我已经看到另一个几乎和我一样的示例设置,它在任何地方都没有任何module.hot.accept() 调用,但我看不出我的设置与其他设置有什么不同。

我们将不胜感激。

【问题讨论】:

标签: node.js express webpack webpack-dev-server webpack-hmr


【解决方案1】:

经过大量挖掘,我找到了问题的答案。我正在像这样创建我的基础 React “类”:

class Application = () => {
  return (
    <div id="maincontent">
      <MainMenu />
      <ScreenContents />          
    </div>
  )
};

这对于 HMR 是不支持的,即使它受到 React 的支持。

我必须像这样明确地创建我的课程:

class Application extends React.Component{
  render (){
    return (
      <div id="maincontent">
        <MainMenu />
        <ScreenContents /> 
      </div>
    );
  }
};

然后 HMR 就可以正常工作了 :)

编辑:根据@akoskm cmets 的说法,webpack 配置文件中的 babel 配置似乎也可能是一个问题。所以这里是相关部分:

通天塔设置

var babelSettings = {
    presets: ['react', 'es2015', 'stage-2'],
    env: {
        development: {
            plugins: [
                ['react-transform', {
                    transforms: [
                        { 
                            transform: 'react-transform-hmr',
                            imports: [ 'react' ],
                            locals: [ 'module' ]
                        }
                    ]
                }]
            ]
        }
    }
};

预设和环境的东西对你来说可能并不完全相同,但react-transform 的东西是这里的重要部分。

加载器

{ 
    test: /\.(js|jsx)$/,
    loaders: ['babel?' + JSON.stringify(babelSettings)],
    exclude: /node_modules/
}

【讨论】:

  • 这绝对有帮助,但我认为还有更多,因为我使用几乎相同的方式来定义我的基本 React 类:github.com/archistackt/kts/blob/master/components/app.js 但我仍然以相同的方式结束像你一样的错误。你知道为什么吗?
  • @akoskm - 你解决了吗?除了创建 React 类之外,我还在 webpack 配置中更改了我的 babel loader 设置。如果您仍然需要帮助,请告诉我,我们会尽力解决的 :)
  • 感谢@Øyvind Bråthen。我没有机会看这个项目,但我会在接下来的几天内完成它,如果我能完成它,我会告诉你。我在之前的内容中链接的存储库包含我当前使用的 webpack 配置:github.com/archistackt/kts/blob/master/webpack.config.js
  • 我刚刚检查了这个,但仍然无法正常工作。这是我的 babel loader 配置:github.com/archistackt/kts/blob/master/webpack.config.js#L22
  • @akoskm - 我现在从我的项目中添加了 babel 设置,因为它们与你的有很大不同。我认为“react-transform-hmr”是您拼图中缺少的部分。让我知道结果如何:)
猜你喜欢
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 2022-01-28
  • 2016-01-13
  • 2023-03-05
  • 2012-07-19
  • 1970-01-01
相关资源
最近更新 更多