组件未使用 React 热加载器重新加载

Component not reloaded with react hot loader

https://github.com/James2516/hot-reload

我正在尝试将 hot loader 添加到现有的 webpack 项目中。

它检测到文件更改但没有重新加载组件。

重现:

  1. yarn && yarn start
  2. 更改src/App.js内容

示例取自 https://gaearon.github.io/react-hot-loader/getstarted/#step-2-of-3-using-hmr-to-replace-the-root-component,但您似乎已经遵循了本指南。

第一个问题是 [HMR] Waiting for update signal from WDS... 被打印到控制台两次,并且任何尝试的重新编译也会发生两次。这是由于 ./config/webpack/Dev.js 中的 entry 是:

entry: [
  'webpack-dev-server/client?http://localhost:4545/',
  'webpack/hot/only-dev-server',
  'react-hot-loader/patch',
  './client.js',
]

指南的前几个步骤的入口点为:

[
  'webpack-dev-server/client?http://0.0.0.0:3000', // WebpackDevServer host and port
  'webpack/hot/only-dev-server', // 'only' prevents reload on syntax errors
  './scripts/index' // Your app's entry point
]

第 3a 步 第 3 步(共 3 步):添加 React Hot Loader 以保留组件状态 指示您修改 [= webpack.config.js 的 21=] 看起来像:

[
  'react-hot-loader/patch', // RHL patch
  './scripts/index' // Your app's entry point
]

react-hot-loader 处理这两个条目之前所做的事情,因此可以将它们替换为 'react-hot-loader/patch'.

因此您的新入口点应该是:

[
  'react-hot-loader/patch',
  './client.js'
]

接下来,同一部分中的步骤 3b 的代码片段如下所示:

if (module.hot) {
  module.hot.accept('./containers/rootContainer.js', () => {
    const NextRootContainer = require('./containers/rootContainer').default;
    render(NextRootContainer);
  });
}

将您的 module.hot 块更改为:

if (module.hot) {
  module.hot.accept('./App', () => {
    const newApp = require('./App').default;
    render(newApp);
  }
}

正确地重新加载组件,因此遵循 步骤 3c 破坏 HMR 是没有意义的。

c. Webpack 2 has built-in support for ES2015 modules, and you won’t need to re-require your app root in module.hot.accept. The example above becomes:

if (module.hot) {
  module.hot.accept('./containers/rootContainer', () => { 
   render(RootContainer) });
}

Note: To make this work, you’ll need to opt out of Babel transpiling ES2015 modules by changing the Babel ES2015 preset to be

"presets": [["es2015", { "modules": false }]]

您在 .babelrc 中做对了。唯一的问题是在 ./config/webpack/Base.js 你有:

loader: 'babel-loader',
query: {
  presets: ['es2015', 'react', 'stage-2']
}

这会导致 babel-loader 使用这些预设而不是 .babelrc 中定义的预设。删除此规则中的 query 并将 .babelrc 中的 presets 更改为:

"presets": [["es2015", { "modules": false }], "react", "stage-2"

使用您的 module.hot 块正确启用 HMR:

if (module.hot) {
  module.hot.accept('./App', () => { render(App); });
}