webpack-contrib / webpack-hot-middleware

Webpack hot reloading you can attach to your own server
MIT License
2.34k stars 296 forks source link

[HMR] Cannot find update (Full reload needed) #135

Open mrmartineau opened 8 years ago

mrmartineau commented 8 years ago

I apologise if this has been submitted before, but I am running into problems with HMR. I am trying to implement HMR in my framework and thought it was working until recently. Now whenever the modules are updated, the HMR reloads the page indefinitely. The error output is below:

[HMR] Cannot find update (Full reload needed)
[HMR] (Probably because of restarting the server)
[HMR] Reloading page

I am using a slightly out of the ordinary setup: browsersync as my server, webpack for js compilation and my config is below:

Browsersync/HMR setup

/**
 * gulp serve
 * Gulp task to run Browsersync server
 */
const path = require('path');
const gulp = require('gulp');
const browserSync = require('browser-sync').create();
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const config = require('../config');
const webpackConfig = require('./webpack.config.js');
const compiler = webpack(webpackConfig);

gulp.task('serve', ['watcher'], () => {
    webpackConfig.plugins.push(
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    );

    for (const key in config.js.entryPoints) {
        config.js.entryPoints[key].push('webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true');
    }

    browserSync.init({
        server: {
            baseDir: './',
        },

        middleware: [
            webpackDevMiddleware(compiler, {
                stats: 'errors-only',
                publicPath: path.resolve(webpackConfig.output.publicPath),
            }),
            webpackHotMiddleware(compiler),
        ],

        files: [
            `${config.css.distDir}/**/*.css`,
            // `${config.js.distDir}/**/*.js`,
            `${config.img.distDir}/**/*`,
            `${config.svg.distDir}/**/*`,
            '**/*.html',
        ],
    });
});

Webpack config

/**
 * Webpack config
 */
const path = require('path');
const webpack = require('webpack');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const config = require('../config');

const webpackConfig = {
    entry: config.js.entryPoints,
    output: {
        path: path.resolve(`${config.js.distDir}`),
        publicPath: '/',
        filename: '[name].js',
    },
    devServer: {
        inline: true,
        port: 3000,
        stats: 'errors-only',
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                //exclude: /node_modules/,
                loader: 'babel',
                query: {
                    // presets: [
                    //  'es2015',
                    // ],
                    cacheDirectory: true,
                },
            },
        ],
    },
    devtool: 'source-map', // Source maps
    plugins: [
        // Watcher doesn't work well if you mistype casing in a path so we use
        // a plugin that prints an error when you attempt to do this.
        // See https://github.com/facebookincubator/create-react-app/issues/240
        new CaseSensitivePathsPlugin(),
    ],
};

if (process.env.RELEASE) {
    webpackConfig.plugins.push(
        new webpack.optimize.DedupePlugin(),

        // Minify the code using Uglify
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
            },
            output: {
                comments: false,
            },
        }),

        new webpack.BannerPlugin(config.misc.banner, {
            raw: true,
        })
    );
}

module.exports = webpackConfig;

Am I doing anything obviously wrong?

glenjamin commented 8 years ago

It looks like you have config in there for both webpack-dev-server and webpack-hot-middleware, which cannot both be used together.

I'm not entirely sure that's the problem - but try removing the devServer section from the webpack config.

rchristensen commented 8 years ago

Apologies for hijacking, but I'm having the same issue only with express. My relevant code in server.js:

// If developing on a local machine, use webpack-dev-middleware to provide auto-reloading assets
if (process.env.AUTO_BUILD == true) {
    const config = require('./webpack.config.dev');
    const compiler = webpack(config);

    app.use(require('webpack-dev-middleware')(compiler, {
        noInfo: true,
        publicPath: config.output.publicPath,
        stats: { colors: true }
    }))

    app.use(require ('webpack-hot-middleware')(compiler, {
        log: console.log,
        reload: true
    }))
}

app.use('/', express.static(__dirname + '/'));

My webpack config:

const webpack = require('webpack');
const path = require('path');

require('dotenv').config();

module.exports = {
    target: 'node',
    entry: [
        'react-hot-loader/patch',
        'webpack-hot-middleware/client',
        ${path.join(__dirname, 'index.js')},
        ],
    output: {
        path: path.join(__dirname, 'dist'),
        publicPath: '/dist',
        filename: 'bundle.js'
    },
    devtool: process.env.NODE_ENV === 'production' ? false : "eval",
    plugins: [
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ],
    module: {
        loaders: [
            {
                test: /\.scss$/,
                include: /src/,
                loaders: [
                    'style',
                    'css',
                    'autoprefixer?browsers=last 3 versions',
                    'sass?outputStyle=expanded'
                ]
            },
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                loaders: [
                    'url?limit=8192',
                    'img'
                ]
            },
            {
                test: /\.jsx?$/,
                exclude: '/node_modules/',
                loaders: [ 'babel' ]
            }, {
                test: /\.css$/,
                loader: 'style-loader!css-loader'
            }
        ]
    }

};

Console output:

[HMR] connected
client.js:127 [HMR] bundle rebuilding
client.js:131 [HMR] bundle rebuilt in 713ms
process-update.js:29 [HMR] Checking for updates on the server...
process-update.js:39 [HMR] Cannot find update (Full reload needed)cb @ process-update.js:39(anonymous function) @ bundle.js:210hotDownloadManifest @ bundle.js:11hotCheck @ bundle.js:206check @ process-update.js:65module.exports @ process-update.js:30processMessage @ client.js:142handleMessage @ client.js:66
process-update.js:40 [HMR] (Probably because of restarting the server)cb @ process-update.js:40(anonymous function) @ bundle.js:210hotDownloadManifest @ bundle.js:11hotCheck @ bundle.js:206check @ process-update.js:65module.exports @ process-update.js:30processMessage @ client.js:142handleMessage @ client.js:66
glenjamin commented 8 years ago

@rchristensen Does the server restart after changes?

rchristensen commented 8 years ago

@glenjamin It doesn't seem to? Console output:

Express server listening on port 3000
webpack built 7856f8a4727533a33ad5 in 13231ms
webpack building...
webpack built 94c6b0b9eb9cd4f2fb85 in 793ms
webpack building...
webpack built 44d5a3e90920c7d75c73 in 713ms
glenjamin commented 8 years ago

That's odd, I'd double-check your publicPath setting, the part which is failing is when webpack attempts to download the manifest from webpack-dev-middleware - which isn't something directly managed by this package.

rchristensen commented 8 years ago

Alright, that helps, thanks for the insight!

rchristensen commented 8 years ago

For what it's worth, my issue was using target: node instead of target: web, not sure if it'll help OP but worth a shot.

nozzlegear commented 8 years ago

I just ran into this issue too. In my case it was because my publicPath option for webpack-dev-middleware ended with a trailing slash. Removing that fixed the problem for me.

app.use(require('webpack-dev-middleware')(compiler, {
    publicPath: "/dist", // Do not end publicPath with a / 
    watchOptions: {
        poll: true
    },
    stats: {
        colors: true
    }
}));
pastelsky commented 7 years ago

I'm facing a very similar issue. As soon as I start the server, I get:

GET http://localhost:4000/public/fe242263d0577251a5c3.hot-update.json 404 (Not Found)
[HMR] Cannot find update (Full reload needed)
[HMR] (Probably because of restarting the server)

I'm using write-file-plugin for webpack, and the funny thing is, that this missing hot-update.json file won't be generated until after I've made my first edit in any component. Somehow the request seems to go out before, leading to the 404.

Notably, all successive HMR updates work fine just fine.

Hot middleware

// Hot middleware config
hotMiddleware(compiler, {
    log: false,
  }

Dev middleware

// Dev middleware config
devMiddleware(compiler, {
    watchOptions: {
      ignored: /node_modules/,
    },
    stats: {
      colors: true,
      assets: true,
      version: false,
      hash: false,
      timings: true,
      chunks: false,
      chunkModules: false,
    },
  }
glenjamin commented 7 years ago

@pastelsky I'm not 100% sure, but try removing the false entries from your stats options - I think some of those are needed by hot middleware.

bonesoul commented 7 years ago

I' having the same issue;

webpack.config;

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    frontend: ['./assets/js/frontend/frontend.js', 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000'],
    backend: ['./assets/js/backend/backend.js', 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000']
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, './public/dist'),
    publicPath: '/dist/'
  },
  module: {
    rules: [
      { test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: '$' }] }, // globally expose $ for jQuery.
      { test: /mixer\.js$/, use: [{ loader: 'expose-loader', options: 'recipeMixer' }] },
      { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader'] }) }, // extra css files.
      { test: /\.(jpe?g|gif|png|eot|svg|woff|woff2|ttf)$/, use: 'file-loader' }, // font & image loader.
      //{ test: /\.js$/, include: [ path.resolve(__dirname, 'assets/js') ], use: [{ loader: 'babel-loader', options: { presets: ['es2015'] }, }], }, // es6 babel loader.
    ]
  },
  resolve: {
    modules: [ 'node_modules' ],
    alias: { jquery: require.resolve('jquery') }
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({ name: 'common', filename: 'common.js' }), // commons.
    new ExtractTextPlugin({ filename: '[name].css', disable: false, allChunks: true }), // extract css.
    new webpack.ProvidePlugin({ $: 'jquery', jquery: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery', 'window.$': 'jquery' }), // provide jquery.
    new webpack.IgnorePlugin(/\.\/locale$/), // Fixes warning in moment-with-locales.min.js; Module not found: Error: Can't resolve './locale' in ...
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ],
  devtool: 'source-map'
};

middlewares;

const webpack = require('webpack');
const config = require('../../../webpack.config.js');
const dev = require('webpack-dev-middleware');
const hmr = require('webpack-hot-middleware');
const compiler = webpack(config);

exports.compiler = function () {
  return dev(compiler, {
    noInfo: true,
    publicPath: config.output.publicPath
  });
};

exports.hmr = function () {
  return hmr(compiler);
};

browser output;

[HMR] Cannot find update (Full reload needed)
[HMR] (Probably because of restarting the server)
GET https://localhost:4443/__webpack_hmr net::ERR_INCOMPLETE_CHUNKED_ENCODING

express server output;

webpack built 736e2ec083f3707a4a39 in 6148ms
GET /dist415bd7e4ec4eb6daa42b.hot-update.json 404 99.006 ms - -

i clearly get a 404 there.

any ideas?

wwwebman commented 6 years ago

Hello, guys! When we tried to "proxying" our local server with browserSync we got the same bug. As a result, the page was reloading all the time - issue

We used Wordpress, so the solution that prevents reloading is to change publicPath: publicPath: http://localhost:8080/wp-content/themes/THEME_NAME/assets/js/

more about - solution

kgroat commented 6 years ago

I had the same error message, and realized that target: 'node' was set in my webpack config accidentally. Taking that out fixed it like a charm.

Tonysmark commented 3 years ago

Same issue but by changing webpack-hot-middleware/client to webpack-hot-middleware/client?path=/__webpack_hmr solve this problem

kudi82 commented 6 months ago

I have the same warning: [Warning] [HMR] Cannot find update (Full reload needed) [Warning] [HMR] (Probably because of restarting the server)

In my case it is like this:

I have a server which provides a widgets.js which is built by webpack. Somewhere in this widgets.js I found: /**/ / webpack/runtime/getFullHash / /**/ (() => { /**/ __webpack_require__.h = () => ("c2e5f0b82b674807953e") /**/ })(); /**/

Inside this widgets.js I have a React Component which prints "Hello World". Everything is fine. I can start the server for hot reloading using these: "webpack-dev-middleware": "^7.2.1" "webpack-hot-middleware": "^2.26.1"

If I now change "Hello World" to "Hello Me" it works with hot reloading. When I stop the hot reloading server and start it again it will say it cannot find c2e5f0b82b674807953e because I did not recreate widgets.js with the change from "Hello World" to "Hello Me".