Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HMR/Live Reloading broken after Webpack 5 rc.0 -> rc.1 update #2758

Closed
1 of 2 tasks
Tracked by #149
wojtekmaj opened this issue Oct 6, 2020 · 91 comments
Closed
1 of 2 tasks
Tracked by #149

HMR/Live Reloading broken after Webpack 5 rc.0 -> rc.1 update #2758

wojtekmaj opened this issue Oct 6, 2020 · 91 comments

Comments

@wojtekmaj
Copy link
Contributor

wojtekmaj commented Oct 6, 2020

  • Operating System: macOS Big Sur
  • Node Version: 14.5.0
  • NPM Version: 6.14.5
  • webpack Version: 5.0.0-rc.3
  • webpack-dev-server Version: ^3.10.3
  • Browser: Chrome
  • This is a bug
  • This is a modification request

After upgrading from Webpack 5.0.0-beta.29 to 5.0.0-rc.3, I've noticed that HMR/Live Reloading stopped working, even though no other changes to the code were made.

I investigated by updating it step by step and here's my outcome:

Version Works?
5.0.0-beta.29 Yes ✅
5.0.0-beta.30 Yes ✅
5.0.0-beta.31 Yes ✅
5.0.0-beta.32 Yes ✅
5.0.0-beta.33 Yes ✅
5.0.0-rc.0 Yes ✅
5.0.0-rc.1 No ❌
5.0.0-rc.2 No ❌
5.0.0-rc.3 No ❌

Code

// webpack.config.js
const webpack = require('webpack');
const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');

const isProduction = process.env.NODE_ENV === 'production';
const isDevelopment = !isProduction;

const publicPath = process.env.PUBLIC_URL || '/';

module.exports = {
  mode: isProduction ? 'production' : 'development',
  bail: isProduction,
  entry: {
    src: [
      './src/index.jsx',
    ],
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    publicPath,
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        include: path.resolve(__dirname, 'src'),
        use: 'babel-loader',
      },
    ].filter(Boolean),
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
  ].filter(Boolean),
  devServer: {
    historyApiFallback: true,
    hot: true,
    port: 3000,
  },
};

Expected Behavior

HMR to work on Webpack version 5.0.0-rc.1 to 5.0.0-rc.3.

Console output in 5.0.0-beta.29 to 5.0.0-rc.0:

[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
[WDS] Live Reloading enabled.

...and of course, on change...

[WDS] App updated. Recompiling...
[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] Updated modules:
[HMR]  - ./components/pages/index.jsx
[HMR] App is up to date.

Actual Behavior

HMR doesn't on Webpack version 5.0.0-rc.1 to 5.0.0-rc.3.

Console output in 5.0.0-rc.3:

[HMR] Waiting for update signal from WDS...

...and silence after that.

I can see that Webpack is rebuilding, so I think Webpack part works fine. Refreshing the page manually also gets me the updated page. So only HMR/Live Reloading part must be broken.

@wojtekmaj wojtekmaj changed the title HMR/Live Reloading broken after Webpack 5 beta.33 -> rc.3 update HMR/Live Reloading broken after Webpack 5 rc.0 -> rc.1 update Oct 6, 2020
@alexander-akait
Copy link
Member

Please create reproducible test repo, I think bug in webpack-dev-server

@wojtekmaj
Copy link
Contributor Author

Managed to narrow it down quite a lot.

Webpack HMR bug repro.zip

@wojtekmaj
Copy link
Contributor Author

Interestingly, removing .browserlistrc seems to fix the issue.

So I compared src.js in both cases looking for answer and found that:

With .browserlistrc (no: when HMR not working) src.js ends with:

/******/ 	
/************************************************************************/
/******/ 	// module cache are used so entry inlining is disabled
/******/ 	// startup
/******/ 	// Load entry module
/******/ 	__webpack_require__("./src/index.jsx");
/******/ 	__webpack_require__("./node_modules/webpack/hot/dev-server.js");
/******/ })()
;

and without .browserlistrc (no: when HMR is working), src.js ends with:

/************************************************************************/
/******/ 	// module cache are used so entry inlining is disabled
/******/ 	// startup
/******/ 	// Load entry module
/******/ 	__webpack_require__("./src/index.jsx");
/******/ 	__webpack_require__("./node_modules/webpack-dev-server/client/index.js?http://localhost:3000");
/******/ 	__webpack_require__("./node_modules/webpack/hot/dev-server.js");
/******/ })()
;

@alexander-akait
Copy link
Member

@wojtekmaj Can you provide .browserlistrc?

@alexander-akait
Copy link
Member

Looks webpack-dev-server thinks it is not browser

@wojtekmaj
Copy link
Contributor Author

wojtekmaj commented Oct 6, 2020

An example is in the repro repo linked above, but I tested these and all of them broke the build for me:

Original:

Chrome >=72
Firefox >=66
IE >=11

Original but lowercase:

chrome >=72
firefox >=66
ie >=11

Thought it's maybe IE so removed and left just Chrome:

Chrome >=72

@wojtekmaj
Copy link
Contributor Author

@evilebottnawi looks like your diagnosis is correct, because adding target: 'web' (which overwrites the default being 'browserlist' since 5.0.0-rc.1) to Webpack config resolves the issue.

@alexander-akait
Copy link
Member

Yes, we need to fix it in webpack-dev-server, hope I will find time on it, anyway you can send a PR

@khalwat
Copy link

khalwat commented Oct 12, 2020

I too am experiencing this issue, which renders HMR inoperative with webpack 5, though I'm using @babel/preset-env rather than .browserlistrc.

But the symptoms are the same, everything builds, but this is all that is output in the console:

[HMR] Waiting for update signal from WDS...

I did confirm, however, that rolling back to:

        "webpack": "5.0.0-beta.29",

causes it to work again as expected:

[HMR] Waiting for update signal from WDS...
index.js:48 [WDS] Hot Module Replacement enabled.
index.js:52 [WDS] Live Reloading enabled.

@khalwat
Copy link

khalwat commented Oct 12, 2020

I can confirm that it works as expected with webpack 5.0.0-rc.0 but breaks with 5.0.0-rc.1 so the error is here somewhere:

https://github.com/webpack/webpack/compare/v5.0.0-rc.0..v5.0.0-rc.1

https://github.com/webpack/webpack/releases/tag/v5.0.0-rc.1

I can also confirm that if I add:

        target: 'web',

…to the base webpack config, that the latest release does indeed work.

@chenxsan
Copy link
Member

chenxsan commented Oct 12, 2020

I've pushed a pull request to fix it, can anyone with the problem try the branch with yarn's resolution? Just adding the below code to package.json and run yarn install --force

  "resolutions": {
    "webpack-dev-server": "git://github.com/chenxsan/webpack-dev-server#bugfix/fix-hmr-browserslist"
  }

@khalwat
Copy link

khalwat commented Oct 12, 2020

Using that @chenxsan I get:

webpack_1  | > webpack-dev-server --config webpack.dev.js --trace-deprecation
webpack_1  |
webpack_1  | Error: Cannot find module '../../client/'
webpack_1  |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15)
webpack_1  |     at Function.resolve (internal/modules/cjs/helpers.js:19:19)
webpack_1  |     at addEntries (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/utils/addEntries.js:39:36)
webpack_1  |     at updateCompiler (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/utils/updateCompiler.js:48:5)
webpack_1  |     at new Server (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/Server.js:72:5)
webpack_1  |     at startDevServer (/var/www/project/buildchain/node_modules/webpack-dev-server/bin/webpack-dev-server.js:106:14)
webpack_1  |     at processOptions (/var/www/project/buildchain/node_modules/webpack-dev-server/bin/webpack-dev-server.js:166:3)
webpack_1  |     at findPort.then (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/utils/processOptions.js:33:9)
webpack_1  |     at process.runNextTicks [as _tickCallback] (internal/process/task_queues.js:52:5)
webpack_1  |     at Function.Module.runMain (internal/modules/cjs/loader.js:880:11)
webpack_1  |     at internal/main/run_main_module.js:21:11
webpack_1  | npm ERR! code ELIFECYCLE
webpack_1  | npm ERR! errno 1
webpack_1  | npm ERR! example-project@1.1.3 debug: `webpack-dev-server --config webpack.dev.js --trace-deprecation`
webpack_1  | npm ERR! Exit status 1
webpack_1  | npm ERR!
webpack_1  | npm ERR! Failed at the example-project@1.1.3 debug script.
webpack_1  | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
webpack_1  |
webpack_1  | npm ERR! A complete log of this run can be found in:
webpack_1  | npm ERR!     /root/.npm/_logs/2020-10-12T05_14_22_391Z-debug.log
fwt_webpack_1 exited with code 1

@chenxsan
Copy link
Member

chenxsan commented Oct 12, 2020

Using that @chenxsan I get:

webpack_1  | > webpack-dev-server --config webpack.dev.js --trace-deprecation
webpack_1  |
webpack_1  | Error: Cannot find module '../../client/'
webpack_1  |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15)
webpack_1  |     at Function.resolve (internal/modules/cjs/helpers.js:19:19)
webpack_1  |     at addEntries (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/utils/addEntries.js:39:36)
webpack_1  |     at updateCompiler (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/utils/updateCompiler.js:48:5)
webpack_1  |     at new Server (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/Server.js:72:5)
webpack_1  |     at startDevServer (/var/www/project/buildchain/node_modules/webpack-dev-server/bin/webpack-dev-server.js:106:14)
webpack_1  |     at processOptions (/var/www/project/buildchain/node_modules/webpack-dev-server/bin/webpack-dev-server.js:166:3)
webpack_1  |     at findPort.then (/var/www/project/buildchain/node_modules/webpack-dev-server/lib/utils/processOptions.js:33:9)
webpack_1  |     at process.runNextTicks [as _tickCallback] (internal/process/task_queues.js:52:5)
webpack_1  |     at Function.Module.runMain (internal/modules/cjs/loader.js:880:11)
webpack_1  |     at internal/main/run_main_module.js:21:11
webpack_1  | npm ERR! code ELIFECYCLE
webpack_1  | npm ERR! errno 1
webpack_1  | npm ERR! example-project@1.1.3 debug: `webpack-dev-server --config webpack.dev.js --trace-deprecation`
webpack_1  | npm ERR! Exit status 1
webpack_1  | npm ERR!
webpack_1  | npm ERR! Failed at the example-project@1.1.3 debug script.
webpack_1  | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
webpack_1  |
webpack_1  | npm ERR! A complete log of this run can be found in:
webpack_1  | npm ERR!     /root/.npm/_logs/2020-10-12T05_14_22_391Z-debug.log
fwt_webpack_1 exited with code 1

Sorry, have no idea what's going on here. Maybe you can remove the resolution and try to edit node_modules/webpack-dev-server/lib/utils/addEntries directly? Just add a browserslist in the webTarget array. I've tested on my computer with the example code @wojtekmaj provides, it seems to be working fine with both webpack 5.0.0-rc.3 and webpack 5.

jtanguy added a commit to sfeir-open-source/talk-control that referenced this issue Oct 12, 2020
Also, browserslist does not seem to work here. See
webpack/webpack-dev-server#2758
@slightlyfaulty
Copy link

@chenxsan's fix works for me.

Seems this issue happens when you have a browserslist entry in your package.json. Modules from ./node_modules/webpack-dev-server/client/ are not included in the output bundle at all. After removing browserslist, they are included correctly.

@chenxsan
Copy link
Member

@slightlyfaulty You're right here. As of webpack v5.0.0-rc.1 https://github.com/webpack/webpack/releases/tag/v5.0.0-rc.1, the target defaults to browserslist if you have browserslist in your project. But webpack-dev-server is not updated yet to follow that change. I think that's why client parts are not included, resulting no socket connected to the server to watch updates.

@thermarthae
Copy link

thermarthae commented Oct 16, 2020

Not sure if that helps, but it looks like this problem also occurs when the target is an array.
For example: target: 'web' works, but target: ['web'] doesn't.

@leodr
Copy link

leodr commented Oct 16, 2020

Not sure if that helps, but it looks like this problem also occurs when the target is an array.
For example: target: 'web' works, but target: ['web'] don't.

Yup, the ability to set arrays as a target also came with webpack 5. Arrays are listed as a valid type in the webpack 5 docs, but not in the webpack 4 docs

EDIT: If it helps, my current fix is to specify "web" as a target when developing and "browserslist" as a target when building for production:

target: process.env.NODE_ENV === "development" ? "web" : "browserslist",

@irfanit93
Copy link

Not sure if that helps, but it looks like this problem also occurs when the target is an array.
For example: target: 'web' works, but target: ['web'] don't.

Yup, the ability to set arrays as a target also came with webpack 5. Arrays are listed as a valid type in the webpack 5 docs, but not in the webpack 4 docs

EDIT: If it helps, my current fix is to specify "web" as a target when developing and "browserslist" as a target when building for production:

target: process.env.NODE_ENV === "development" ? "web" : "browserslist",

Removing the target property from webpack.config.js also works fine for me for development purpose.
As you said we can later add the target property when we are building for production.

@akphi
Copy link

akphi commented Aug 30, 2021

@alexander-akait hope you get well soon!

@khalwat
Copy link

khalwat commented Aug 30, 2021

I have a working HMR setup here, in case it's useful to anyone:

https://github.com/nystudio107/craft/blob/craft-webpack/buildchain/webpack-configs/dev-server.config.js

@xavierfoucrier
Copy link

@alexander-akait no problem! Take care of yourself first ✌💊

@myou11
Copy link

myou11 commented Sep 1, 2021

Hi there, I have read through this thread and am not sure why the webpack config for my project does not seem to be working. I know that webpack-dev-server 4.0.0 recently came out a few weeks ago and has removed the need for a workaround of target: 'web' when you have browserslist in your package.json. I also have hot: true in my devServer config object and have not included the HotModuleReplacementPlugin in my webpack config since webpack 5 will include it automatically when hot: true is set.
Aside from that, I'm not sure why my config is not working. I have stripped out my config in this repo so others can see.
I did find this other project that seems to be using the most up to date webpack dependencies (webpack 5 and webpack-dev-server 4) and theirs hot reloads just fine.
You'll notice that in my project, the only console output I get is:

[HMR] Waiting for update signal from WDS...

In the other project by carlrip, they get console output of:

[HMR] Waiting for update signal from WDS...
[webpack-dev-server] Hot Module Replacement enabled.
[webpack-dev-server] Live Reloading enabled.

I think part of my problem is that I'm not getting those last two console logs. Thank you for any help!

@alexander-akait
Copy link
Member

Remove client: false

@myou11
Copy link

myou11 commented Sep 2, 2021

Remove client: false

ah, thank you @alexander-akait! I am assuming that by setting client: false, I also disabled the webSocketTransport property which is how my browser communicates with the webpack-dev-server. I was only intending to disable the overlay, so in effect, I should have only disabled that property specifically:

client: {
    overlay: {
        errors: true,
        warnings: false,
    },
}

@alexander-akait
Copy link
Member

Anyway why you disable warnings? You can filter them, it is better

@myou11
Copy link

myou11 commented Sep 2, 2021

Ah I just didn't want the warnings to show on the overlay, but they still show in the console in the browser and in my terminal. By filtering, are you talking about this stats object? I am unfamiliar with filtering

@alexander-akait
Copy link
Member

@myou11 this https://webpack.js.org/configuration/other-options/#ignorewarnings, ideally you should not have warnings at all or control them by filtering

@alexander-akait
Copy link
Member

@xavierfoucrier

This invitation has expired.

😞

Can you send invite again, sorry...

@xavierfoucrier
Copy link

@alexander-akait done again 😉✌

@alexander-akait
Copy link
Member

@xavierfoucrier here interesting case, because hot: true by default we are trying to apply hot replacement, but without watchFiles dev server doesn't known what change in your twig template requires live reload, for this case we implement watchFiles, yes, webpack recompiling changes twig templates due twig-html-loader, in theory we can get updatedModules and check if it is empty it means nothing was changed and if compilation hash was changed it means you need to reload browser, I think we can mark this as feature

@xavierfoucrier
Copy link

@alexander-akait Ha ok I understand. Glad to share interesting use case with webpack team 🍻😉 I will follow the associated issue, just let me know if you still need access to the repository because it will evolve in the near weeks. Thanks!

@alexander-akait
Copy link
Member

@xavierfoucrier yep, I will ping you if will need more information (but I have local version)

@dbehmoaras
Copy link

dbehmoaras commented Sep 7, 2021

having the same issue. tried every single fix mentioned here and still no luck......

const path = require("path");
require("dotenv").config();
const webpack = require("webpack");

module.exports = {
  mode: process.env.NODE_ENV,
  entry: {
    main: ["./src/client/index.tsx"],
  },
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./build"),
  },
  devtool: "inline-source-map",
  resolve: {
    extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"],
  },
  module: {
    rules: [
      {
        test: /\.(t|j)sx?$/,
        use: { loader: "ts-loader" },
        exclude: /node_modules/,
      },
      {
        enforce: "pre",
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "source-map-loader",
      },
      { test: /\.js$/, loader: "source-map-loader" },
      {
        test: /\.s[ac]ss$/i,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin({
      template: "./index.html",
    }),
  ],
  target: "web",
  devServer: {
    hot: true,
    port: process.env.DEV_PORT,
    historyApiFallback: true,
    static: {
      publicPath: "./build",
    },
    // contentBase: path.resolve(__dirname, "./build"),
    proxy: {
      "/": {
        target: `http://localhost:${process.env.SERVER_PORT}`,
        secure: false,
      },
    },
  },
};

@alexander-akait
Copy link
Member

@dbehmoaras Please provide reproducible test repo

@dbehmoaras
Copy link

dbehmoaras commented Sep 8, 2021

Sure thing @alexander-akait thank you for offering your help. Please see below for a link to the repo. The app itself doesn't do anything yet. I've been focused on setting up the environment first before adding any functionality. The issue I'm running into is that when I change the text content inside of App.tsx, the change is only reflected after manually re-building bundle.

https://github.com/ResearchGlobal/stockwatch

The hierarchy is as follows: index.tsx renders App.tsx, which only includes a single div with some inner HTML. Feel free to ignore the Context provider for the time being as well as the testing suite. There is also a server.ts file which handles the back end inside the server directory. To get started - npm install, npm run build, and then npm run dev.

@alexander-akait
Copy link
Member

alexander-akait commented Sep 8, 2021

[webpack-dev-server] "hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.

remove:

new webpack.HotModuleReplacementPlugin({
      template: "./index.html",
    }),

It is automatically enable when hot: true (default).

static: {
      publicPath: "./build",
    },

to

static: {
      directory: "./build",
    },

Other note:

resolve: {
    // `...` extends default extensions + your add own
    extensions: [".web.js", ".ts", ".tsx", "..."],
  },

But the main problems is here:

proxy: {
      "/": {
        target: `http://localhost:${process.env.SERVER_PORT}`,
        secure: false,
      },
    },

You proxy all request to your server, you need keep, for example:

// Only HTML passed to your server
proxy: {
      "/": {
        target: `http://localhost:${process.env.SERVER_PORT}`,
        secure: false,
        bypass: function (req, res, proxyOptions) {
          if (req.headers.accept.indexOf('html') !== -1) {
            console.log('Skipping proxy for browser request.');
            return '/index.html';
          }
        },
      },
    },

Also not you need to add build/index.html - <div id="root"></div>

@dbehmoaras
Copy link

@alexander-akait thank you very much. I will try this right away and let you know if it helps.

@dbehmoaras
Copy link

@alexander-akait worked like a charm! Thank you very much for your help! I am very grateful

@dbehmoaras
Copy link

@alexander-akait quick follow up - if i add a proxy, is it correct to assume that i would need to add the bypass in the same way?

@alexander-akait
Copy link
Member

If your requests are overlapping, i.e. you have /public/image.png for main server and /public/image.png for dev server, hard to say what is the better for you, I think you need handle only html based requests

@dbehmoaras
Copy link

ok that makes sense, thanks!

@Jingotto
Copy link

I also had a problem with the DevServer, the pages were not refreshed. I added this code and it helped me.

static: {
directory: path.join(__dirname, 'src'),
watch: true,
},

P.S. Maybe I didn’t understand the problem, sorry, i’m a noob. But if someone faced the same problem it helps.

@vaibhav023
Copy link

Feel free to ping me

@CHENJIAMIAN
Copy link

use cnpm install , resolve.symlinks: false, make it happen.
You can see this troubleshooting.html#symbolic-links-in-node-modules

@amrfhn
Copy link

amrfhn commented Aug 4, 2022

Hello, i come from 2022, is there any updates regarding the live reloading issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.