hot reloading not working unless I have ?reload=true
orpheus opened this issue · comments
App won't hot reload unless I add '?reload=true' to my webpack-hot-middleware entry point in the webpack config.
The rest of my config is set up exactly according to docs. I'm using it along with react-hot-loader which is also set up according to docs.
//webpack.config.js
module.exports = {
entry: [
'react-hot-loader/patch', // RHL patch
'webpack-hot-middleware/client?reload=true', //note that it reloads the page if hot module reloading fails; without this query, hmr fails
'./client/src/index.js'
],
plugins: [
new webpack.HotModuleReplacementPlugin(),
...
//server.js
server.use(webpackDevMiddleware(compiler, {
noInfo: true, publicPath: webpackConfig.output.publicPath,
}));
server.use(webpackHotMiddleware(compiler));
//package.json
"babel": {
"plugins": [
"react-hot-loader/babel"
],
"presets": [
"env",
"react",
"stage-2"
]
Is there something I'm missing? I have the react-hot-loader component wrapping my root component in my index.js; so I don't know why it won't work without the reload query.
What info do you get in the browser console when reloading fails?
process-update.js?e13e:81 [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 https://webpack.js.org/concepts/hot-module-replacement/ for more details.
I got the same error as @Always-sunny:
college_verify.js:58428 Ignored an update to unaccepted module 701 -> 602 -> 406
college_verify.js:58501 [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 https://webpack.js.org/concepts/hot-module-replacement/ for more details.
college_verify.js:58509 [HMR] - ./app/components/college_verify/CollegeVerify.jsx
However if I add the reload=true
to the params:
webpack-hot-middleware/client?path=http://www.website.com:8080/__webpack_hmr
It allows the browser to refresh the entire page on HMR update.
I'd love to get this to work without having to do a full browser refresh. Any suggestions?
You should tell your application how to deal with the changes.
Try to use the module.hot.accept()
function provided by webpack hmr.
Here is an example:
//imports
...
const renderApp = () => {
ReactDOM.hydrate((
<App />
), document.getElementById('root'));
};
// This is needed for Hot Module Replacement
if (module.hot) {
module.hot.accept('./App', () => renderApp());
}
@ungerpeter Already implemented.
Ditto
The same situation with
react-hot-loader v.4.0.0
,
webpack v.4.2.0
,
webpack-dev-middleware v.3.0.1
,
webpack-hot-middleware v.2.21.2
.
I use new approach:
// client/index.js
import React from 'react';
import { render } from 'react-dom';
import App from './components/App';
render(
<App/>,
document.getElementById('root')
);
// components/App.js
import React, { Component } from 'react';
import { hot } from 'react-hot-loader'
class App extends Component {
render() {
return <h1>Hello world from react!</h1>
}
}
export default hot(module)(App);
// server/index.js
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleWare from 'webpack-hot-middleware';
import webpackConfig from '../webpack.config';
const app = express();
const compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
hot: true,
publicPath: webpackConfig.output.publicPath
}));
app.use(webpackHotMiddleWare(compiler));
// .babelrc
{
"presets": ["es2015", "react"],
"plugins": ["react-hot-loader/babel"]
}
// webpack.config.js
export default {
entry: [
'webpack-hot-middleware/client',
path.join(__dirname, 'client/index.js')
],
output: {
path: '/',
publicPath: '/',
filename: 'bundle.js'
},
module: {
rules: [{
test: /\.js$/,
include: [path.join(__dirname, 'client')],
loader: 'babel-loader'
}]
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
]
}
Only adding 'webpack-hot-middleware/client?reload=true',
helps and do reload all pages.
Error messages in console:
Ignored an update to unaccepted module ./client/components/App.js -> ./client/index.js -> 0
[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 https://webpack.js.org/concepts/hot-module-replacement/ for more details.
[HMR] - ./client/components/App.js
I spent yesterday all day. But now suddenly I've found the reason. It needs to add mode: development
in webpack.config
. If mode is undefined or production
the issue is reproduced.
Same here works only with reload=true
....
here is my webpack setup:
webpack.config.js:
const path = require('path')
const fs = require('fs')
const webpack = require('webpack')
const CopyPlugin = require('copy-webpack-plugin')
process.env['NODE_CONFIG_DIR'] = path.join(__dirname, '../config')
process.env['BABEL_ENV'] = path.join(__dirname, 'babel.config.json')
const config = require('config')
const clientDir = path.join(__dirname, '../build')
if (!fs.existsSync(clientDir)) {
fs.mkdirSync(clientDir)
}
module.exports = {
mode: config.get('env'),
stats: 'errors-warnings',
infrastructureLogging: {
level: 'warn'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new CopyPlugin([
{
from: path.join(__dirname, 'public'),
to: clientDir
}
])
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cwd: './client'
}
}
}
]
},
entry: [
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true',
path.join(__dirname, 'src/index.js')
],
output: {
path: clientDir,
filename: 'js/bundle.js',
publicPath: '/'
}
}
express.js:
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpackHotMiddleware = require('webpack-hot-middleware')
const webpackConfig = require('../../client/webpack.config.js')
const compiler = webpack(webpackConfig)
app.use(
webpackDevMiddleware(compiler, {
stats: webpackConfig.stats,
publicPath: webpackConfig.output.publicPath
})
)
app.use(webpackHotMiddleware(compiler))
Note, my app is a react app. Maybe it doesn't work because I don't use react-hot-loader
module