组件未使用 React 热加载器重新加载
Component not reloaded with react hot loader
https://github.com/James2516/hot-reload
我正在尝试将 hot loader 添加到现有的 webpack 项目中。
它检测到文件更改但没有重新加载组件。
重现:
yarn && yarn start
- 更改
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); });
}
https://github.com/James2516/hot-reload
我正在尝试将 hot loader 添加到现有的 webpack 项目中。
它检测到文件更改但没有重新加载组件。
重现:
yarn && yarn start
- 更改
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); });
}