【问题标题】:Webpack Hot Module Replacement + ReactWebpack 热替换模块 + React
【发布时间】:2018-09-22 18:45:29
【问题描述】:

可能这是成千上万个类似问题之一,但我仍然没有看到任何关于如何使 HMR 真正工作的答案。

我做了所有这些操作,在docs 中进行了描述,并且在您可以在互联网上找到的每个答案中:

  • 启用 webpack-dev-server 的“热”选项
  • 添加webpack-dev-server/client?{host:port}webpack/hot/only-dev-server入口点
  • new webpack.HotModuleReplacementPlugin() 添加到插件(以及 NamedModulesPlugin)
  • react-hot-loader 文档中的每一步

现在我有什么了。

假设我的应用看起来像这样:

<ReactRouter>
  <App>
    <AppRouter />
  </App>
</ReactRouter>

AppRouter 在哪里

<Switch>
  <Route path="..." component={Page} />
  ...
</Switch>

Page 就是&lt;div&gt;some text&lt;div&gt;

根据文档,我在 App 模块中:

import { hot } from "react-hot-loader"
export default hot(module)(App)

然后尝试将Page 组件中的文本修改为“新文本”。

在控制台中,我看到确实启用了 HMR:

[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] Updated modules:
[HMR]  - ./Page.js
[HMR]  - ./AppRouter.js
[HMR]  - ./App.js
[HMR] App is up to date.

屏幕上的文字确实会更新为“新文字”。到目前为止一切顺利。

然后我再次将文本更新为“新文本 2”,然后看到:

Ignored an update to unaccepted module ./Page.js -> ./AppRouter.js -> ./App.js
[HMR] The following modules couldn't be hot updated: (They would need a full reload!)
[HMR]  - ./Page.js

react-hot-loader 文档中没有关于此的任何内容

但是好的,也许那个文档有点不正确。毕竟,webpack 自己的文档明确表明我们应该在代码中使用 module.hot.accept(...)

所以在App.js 我愿意:

if (module.hot) {
  module.hot.accept("./AppRouter", () => {
    console.log("It works!")
  })
}

然后刷新页面,再次尝试修改Page组件。

现在控制台显示如下:

[WDS] App hot update...
[HMR] Checking for updates on the server...
App.js:20 It works!
[HMR] Updated modules:
[HMR]  - ./Page.js
[HMR]  - ./AppRouter.js
[HMR]  - ./App.js
[HMR] App is up to date.

但是浏览器中的文本没有更新。即,HMR 已启用但不执行任何操作。

后续更新说:

[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] Updated modules:
[HMR]  - ./Page.js
[HMR] App is up to date.

所以至少我们用unaccepted changes 修复了之前的错误——但浏览器中仍然没有任何变化。

我尝试在 App 装饰有 hot(module) 和不是时都使用 module.hot.accept(...) - 结果是一样的。

然后……接下来呢?我做了我在官方文档中可以找到的一切,但没有任何效果。我究竟做错了什么?

(请不要问“在我们交谈之前提供完整的 webpack 配置”。这都是默认的,根据 webpack 文档中的示例。不要浪费我们的时间)

【问题讨论】:

    标签: reactjs webpack hot-reload


    【解决方案1】:

    当你接受一个文件时,你必须自己做这些事情(例如交换组件)。所以做某事。像这样:

    if (module.hot) {
      module.hot.accept("./AppRouter", () => {
        const NewAppRouter = require('./AppRouter').default;
        const newApp = (
           <ReactRouter>
              <App>
                 <NewAppRouter />
              </App>
           </ReactRouter>
        );
        ReactDom.render(newApp, container);
      });
    }
    

    当文件更改时,我会在此处收到通知。然后我需要更改的文件并使用新文件重新渲染我的应用程序。这在您使用像 redux 或 mobx 这样的状态管理库时效果最佳,因为您的应用程序的状态不会在您重新渲染应用程序时发生变化。

    【讨论】:

      猜你喜欢
      • 2017-06-20
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 2017-06-28
      • 2018-01-17
      • 2018-05-30
      • 1970-01-01
      • 2016-04-30
      相关资源
      最近更新 更多