Navigation Menu

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

Webpack 5 does not re render #252

Closed
joacub opened this issue Nov 12, 2020 · 51 comments
Closed

Webpack 5 does not re render #252

joacub opened this issue Nov 12, 2020 · 51 comments

Comments

@joacub
Copy link

joacub commented Nov 12, 2020

With webpack 5 is not re-rendering the changes, seems like is working and the files changes but the visual changes never happens, i debuged the perfomReactRefresh function and the changes are there, but the browser never re render with the changes. I have to reload the browser for see the changes

@twgraham
Copy link

If you're using browserslist in your build, it's probably related to the issue here and is a dup of this one. If so, you might want to set your target to web in development and browserslist in production as mentioned here

@joacub
Copy link
Author

joacub commented Nov 12, 2020

i removed the browser list and still the same, I will keep looking around that but I already read all of that and still not refreshing, how I said I debuged the performRefresh and the code is new in the refresh but never refresh the browser

@joacub
Copy link
Author

joacub commented Nov 13, 2020

I already tested and looks like is working and console says modules update but never refresh the page with the changes.

the only thing is nor working is the re render but Webpack is doing the refresh and the console says [HMR] modules updated

[WDS] App hot update...
log.js:24 [HMR] Checking for updates on the server...
2index.js?http://localhost:3001:103 [WDS] 99% - done (plugins).
index.js?http://localhost:3001:103 [WDS] 99% - .
2index.js?http://localhost:3001:103 [WDS] 99% - cache (store build dependencies).
2index.js?http://localhost:3001:103 [WDS] 99% - cache (begin idle).
index.js?http://localhost:3001:103 [WDS] 100% - Compilation completed.
websocket.js:124 WebSocket connection to 'ws://localhost:3000/ws/?EIO=3&transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
WS.doOpen @ websocket.js:124
Transport.open @ transport.js:84
Socket.open @ socket.js:250
Socket @ socket.js:122
Socket @ socket.js:28
Manager.open.Manager.connect @ manager.js:226
eval @ manager.js:544
log.js:24 [HMR] Updated modules:
log.js:24 [HMR]  - ./src/containers/Home/Home.js
log.js:24 [HMR] App is up to date.

@joacub
Copy link
Author

joacub commented Nov 13, 2020

even more the code is refreshed the only thing is not working is the re-render, if I click in the navigation link and go back clicking on the home page the home page has the changes. so it is working just the RE-RENDER action is not doing.

Also how other user comment parent folders are not refreshing even navigating for the web.

@pmmmwh
Copy link
Owner

pmmmwh commented Nov 13, 2020

Hi, can you describe more how your app is structured, provide more info on webpack config and versions of dependencies used (webpack, react, react refresh, etc.)

Or even better, provide a reproducible example.

@joacub
Copy link
Author

joacub commented Nov 13, 2020

Hi, can you describe more how your app is structured, provide more info on webpack config and versions of dependencies used (webpack, react, react refresh, etc.)

Or even better, provide a reproducible example.

Hi, im using webpack v5, webpack serve —hot, react 17 with universal-webpack integration. All aparently is working but never refresh or re-render action is not performed, but files changes, parent components never was refreshed, needs a hard relod.

Sorry i writing from the mobile.

@pmmmwh
Copy link
Owner

pmmmwh commented Nov 15, 2020

Hi, im using webpack v5, webpack serve —hot, react 17 with universal-webpack integration. All aparently is working but never refresh or re-render action is not performed, but files changes, parent components never was refreshed, needs a hard relod.

Sorry i writing from the mobile.

Are you doing SSR? Do you include the Babel plugin and this plugin on server side?

Would you mind creating a sample repo to demonstrate the problem?

@joacub
Copy link
Author

joacub commented Nov 15, 2020

Hi, im using webpack v5, webpack serve —hot, react 17 with universal-webpack integration. All aparently is working but never refresh or re-render action is not performed, but files changes, parent components never was refreshed, needs a hard relod.
Sorry i writing from the mobile.

Are you doing SSR? Do you include the Babel plugin and this plugin on server side?

Would you mind creating a sample repo to demonstrate the problem?

Yes i doing ssr and yes im not including this plugin or nothing relevant to react refresh in ssr builds.

@joacub
Copy link
Author

joacub commented Nov 16, 2020

Hi, im using webpack v5, webpack serve —hot, react 17 with universal-webpack integration. All aparently is working but never refresh or re-render action is not performed, but files changes, parent components never was refreshed, needs a hard relod.
Sorry i writing from the mobile.

Are you doing SSR? Do you include the Babel plugin and this plugin on server side?

Would you mind creating a sample repo to demonstrate the problem?

sorry I have no engouh time to create a repo with the same structure, but probably all the projects with react refresh plugin Webpack 5 will be the same

@pkuczynski
Copy link

pkuczynski commented Nov 17, 2020

Yes, I have the same issue. Changes are not reflected in the UI util I refresh. Was working perfectly fine with webpack 4.x

My current setup:

  • "react": "^16.14.0"
  • "react-refresh": "^0.9.0"
  • "webpack": "^5.5.0"
  • "webpack-dev-server": "3.11.0"

@pkuczynski
Copy link

I dbl checked and in-browser console I see only [HMR] Waiting for update signal from WDS.... Nothing more. This is my webpack config:

{
    entry: { app: [ './src' ] },
    optimization: {
        splitChunks: {
            cacheGroups: {
                defaultVendors: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                }
            }
        }
    },
    devtool: 'cheap-module-source-map',
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash:8].css'
        }),
        new webpack.HotModuleReplacementPlugin(),
        new ReactRefreshWebpackPlugin()
    ],
    output: {
        path: '...',
        filename: '[name].[contenthash:8].js',
        publicPath: '/'
    },
    resolve: {
        extensions: [ '.ts', '.tsx', '.js', '.jsx' ]
    },
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    ...
                ]
            }
            {
                test: /\.(js|jsx|ts|tsx)$/,
                    exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: { plugins: [ 'react-refresh/babel' ] }
                    },
                    {
                        loader: 'ts-loader',
                        options: { compilerOptions: { module: 'esnext' } }
                    }
                ]
            }
        ]
    },
    devServer: {
        contentBase: '.../public',
        historyApiFallback: true,
        watchContentBase: true,
        host: '0.0.0.0',
        port: 3000,
        publicPath: '/',
        overlay: { warnings: true, errors: true },
        hot: true,
        inline: true,
        https: false
    },
    mode: 'development'
}

Pretty much the same as in webpack4. Not sure what can be wrong?

@joacub
Copy link
Author

joacub commented Nov 17, 2020

I dbl checked and in-browser console I see only [HMR] Waiting for update signal from WDS.... Nothing more. This is my webpack config:

{
    entry: { app: [ './src' ] },
    optimization: {
        splitChunks: {
            cacheGroups: {
                defaultVendors: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                }
            }
        }
    },
    devtool: 'cheap-module-source-map',
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash:8].css'
        }),
        new webpack.HotModuleReplacementPlugin(),
        new ReactRefreshWebpackPlugin()
    ],
    output: {
        path: '...',
        filename: '[name].[contenthash:8].js',
        publicPath: '/'
    },
    resolve: {
        extensions: [ '.ts', '.tsx', '.js', '.jsx' ]
    },
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    ...
                ]
            }
            {
                test: /\.(js|jsx|ts|tsx)$/,
                    exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: { plugins: [ 'react-refresh/babel' ] }
                    },
                    {
                        loader: 'ts-loader',
                        options: { compilerOptions: { module: 'esnext' } }
                    }
                ]
            }
        ]
    },
    devServer: {
        contentBase: '.../public',
        historyApiFallback: true,
        watchContentBase: true,
        host: '0.0.0.0',
        port: 3000,
        publicPath: '/',
        overlay: { warnings: true, errors: true },
        hot: true,
        inline: true,
        https: false
    },
    mode: 'development'
}

Pretty much the same as in webpack4. Not sure what can be wrong?

Hmr is not active. What command did you use for server ?

@pkuczynski
Copy link

webpack serve --progress

@joacub
Copy link
Author

joacub commented Nov 17, 2020

webpack serve --progress

i have that issue before, was because the server does not up the socket, and was waiting to connect.

this is my configuration:

devServer: {
   port,
  contentBase: `http://${host}:${port}`,
  historyApiFallback: true,
  compress: true,
  quiet: true,
  noInfo: true,
  hot: true,
  hotOnly: true,
  inline: true,
  lazy: false,
  overlay: true,
  // injectHot: true,
  liveReload: false,
}

@pkuczynski
Copy link

Arent hot and hotOnly mutually exclusive?

@joacub
Copy link
Author

joacub commented Nov 17, 2020

Arent hot and hotOnly mutually exclusive?

nope, hot is for reload and hontOnly is for does not hard refresh (Browser) in case something happens.

@pkuczynski
Copy link

Same settings, yet nothing besides [HMR] Waiting for update signal from WDS.... Was working totally fine with webpack4 so I am getting clueless :(

@pkuczynski
Copy link

Found a source of my issue: webpack/webpack-dev-server#2758 After adding target: 'web' all works fine! :)

@joacub
Copy link
Author

joacub commented Nov 17, 2020

Found a source of my issue: webpack/webpack-dev-server#2758 After adding target: 'web' all works fine! :)

Refresh works?

@pkuczynski
Copy link

Yes!

@pmmmwh
Copy link
Owner

pmmmwh commented Nov 18, 2020

Arent hot and hotOnly mutually exclusive?

nope, hot is for reload and hontOnly is for does not hard refresh (Browser) in case something happens.

They are actually mutually exclusive - webpack-dev-server internally would prefer one over the other I believe.

Also - I think target: 'web' would probably solve your issue too?

@joacub
Copy link
Author

joacub commented Nov 18, 2020

Arent hot and hotOnly mutually exclusive?

nope, hot is for reload and hontOnly is for does not hard refresh (Browser) in case something happens.

They are actually mutually exclusive - webpack-dev-server internally would prefer one over the other I believe.

Also - I think target: 'web' would probably solve your issue too?

I still having no refresh, hmr is working but componentes never re-render

@joacub
Copy link
Author

joacub commented Nov 18, 2020

here is an example not working.

https://github.com/joacub/test-react-refresh

live refresh does not work

@pmmmwh
Copy link
Owner

pmmmwh commented Nov 18, 2020

here is an example not working.

joacub/test-react-refresh

live refresh does not work

I'll take a look tonight - thanks for the reproduction!

@joacub
Copy link
Author

joacub commented Nov 18, 2020

here is an example not working.
joacub/test-react-refresh
live refresh does not work

I'll take a look tonight - thanks for the reproduction!

Thanks, for start the server just run the command npm run dev

@joacub
Copy link
Author

joacub commented Nov 19, 2020

Did you could try ?

@pmmmwh
Copy link
Owner

pmmmwh commented Nov 19, 2020

Did you could try ?

Need more time to investigate - it is a bit of a complex setup ...

@dsngo
Copy link

dsngo commented Nov 25, 2020

@pmmmwh I got a simple test repo that react-fast-refresh doesnt work as well. Please take a look: https://github.com/geart891/testrfr
I have resolved this. What i did was change the default export to name export, load the lib from node_modules instead of the cdns. I think this relates to webpack rather than react-refresh.

@joacub
Copy link
Author

joacub commented Nov 27, 2020

@pmmmwh I got a simple test repo that react-fast-refresh doesnt work as well. Please take a look: https://github.com/geart891/testrfr
I have resolved this. What i did was change the default export to name export, load the lib from node_modules instead of the cdns. I think this relates to webpack rather than react-refresh.

how did you resolve this ?

@joacub
Copy link
Author

joacub commented Nov 27, 2020

@pmmmwh did you test or found the issue ?

@jueinin
Copy link

jueinin commented Nov 29, 2020

@joacub you can update webpack-dev-server@4.x now! it has supported webpack@5. and remember to turn off liveReload option.

@joacub
Copy link
Author

joacub commented Nov 29, 2020

@joacub you can update webpack-dev-server@4.x now! it has supported webpack@5. and remember to turn off liveReload option.

I did, still not working.

@jueinin
Copy link

jueinin commented Nov 29, 2020

@joacub you can update webpack-dev-server@4.x now! it has supported webpack@5. and remember to turn off liveReload option.

I did, still not working.

it works on my project...good luck!

@joacub
Copy link
Author

joacub commented Nov 29, 2020

@joacub you can update webpack-dev-server@4.x now! it has supported webpack@5. and remember to turn off liveReload option.

I did, still not working.

it works on my project...good luck!

🤔, can you share your command to start and the devServer config ?

@joacub
Copy link
Author

joacub commented Nov 29, 2020

I double check, update and recompiling works, react refresh does not work

@jueinin
Copy link

jueinin commented Nov 29, 2020

webpack plugin

image

babel config

image

package.json

image

scripts

image

@jueinin
Copy link

jueinin commented Nov 29, 2020

@joacub this is almost all my config. you can have a try.

@joacub
Copy link
Author

joacub commented Nov 29, 2020

@joacub this is almost all my config. you can have a try.

In my projects still not working, recompiling works but react refresh is not working

@dsngo
Copy link

dsngo commented Nov 29, 2020

@joacub, one simple debug is to copy all your configs to a new repo, and start with just simple <div>Debug</div>. There is no point swimming in your gigantic sample repo.

@joacub
Copy link
Author

joacub commented Nov 29, 2020

There is no point swimming in your gigantic sample repo.

Thats what the sample repo has, just one simple component with it And lazy load component..., this is working before...

@pmmmwh
Copy link
Owner

pmmmwh commented Nov 30, 2020

I'm pretty certain with two fixes you should be able to get the integration working (however they might be complex depending on your setup - especially when you're running SSR).

  1. You probably need to add the entry property to your Webpack configuration files - right now I'm not sure why your project would work (maybe due to default src/index.js from Webpack/toolchain) but what the plugin received as the entry is { main: {} }, which obviously is not parsable by us. If you change that to { main: ['./src/index.js'] } then the auto entry injection from us would work.

  2. You would need to have both the Babel plugin and this plugin wired up for your server (SSR) bundle too. This is because React Refresh runtime depends on the order of injection - it MUST run before ReactDOM - I believe this is true for both server (react-dom/server) and client (react-dom).

Unfortunately due to my time constraints and the complexity of your configuration, I wouldn't be able to dig deeper into this at least for the upcoming week.

@joacub
Copy link
Author

joacub commented Nov 30, 2020

I'm pretty certain with two fixes you should be able to get the integration working (however they might be complex depending on your setup - especially when you're running SSR).

  1. You probably need to add the entry property to your Webpack configuration files - right now I'm not sure why your project would work (maybe due to default src/index.js from Webpack/toolchain) but what the plugin received as the entry is { main: {} }, which obviously is not parsable by us. If you change that to { main: ['./src/index.js'] } then the auto entry injection from us would work.
  2. You would need to have both the Babel plugin and this plugin wired up for your server (SSR) bundle too. This is because React Refresh runtime depends on the order of injection - it MUST run before ReactDOM - I believe this is true for both server (react-dom/server) and client (react-dom).

Unfortunately due to my time constraints and the complexity of your configuration, I wouldn't be able to dig deeper into this at least for the upcoming week.

you are completely right, just adding the entry point to the config this is working again.

I thought the system read the Webpack config to get the entry point.

not needed the second change.

thanks a lot

@pmmmwh
Copy link
Owner

pmmmwh commented Nov 30, 2020

you are completely right, just adding the entry point to the config this is working again.

Happy to know that it worked for you 😀 If you think this is resolved feel free to close the issue.

I thought the system read the Webpack config to get the entry point.

Yes - sort of.

However, in cases where this is ambiguous we could only do a best guess, and in your case we received { main: {} } and after all the parsing and guessing we output the same thing. I guess we could do better by detecting this edge case (AFAIK only happens in Webpack 5 because Webpack 4 won't allow entry to be an empty object).

@joacub
Copy link
Author

joacub commented Dec 1, 2020

you are completely right, just adding the entry point to the config this is working again.

Happy to know that it worked for you 😀 If you think this is resolved feel free to close the issue.

I thought the system read the Webpack config to get the entry point.

Yes - sort of.

However, in cases where this is ambiguous we could only do a best guess, and in your case we received { main: {} } and after all the parsing and guessing we output the same thing. I guess we could do better by detecting this edge case (AFAIK only happens in Webpack 5 because Webpack 4 won't allow entry to be an empty object).

Thanks, will close

@catamphetamine
Copy link

catamphetamine commented Feb 8, 2021

@jueinin

you can update webpack-dev-server@4.x now! it has supported webpack@5. and remember to turn off liveReload option.

There's no such thing as "webpack-dev-server@4.x"

@pmmmwh

However, in cases where this is ambiguous we could only do a best guess, and in your case we received { main: {} } and after all the parsing and guessing we output the same thing. I guess we could do better by detecting this edge case (AFAIK only happens in Webpack 5 because Webpack 4 won't allow entry to be an empty object).

For my Webpack 5 setup, the plugin also didn't work.
But when I added the proposed entry: { main: ['./src/index.js'] } config entry, it seems to have started working.
For Webpack 5 users, that's weird, because Webpack 5 guarantees everything working without any entry config.
You should update the README to reflect the requirement of having an entry: { main: ['./src/index.js'] } workaround for people that use Webpack 5 defaults.
Overall, the setup process is convoluted and ambiguous with all those variations of plugins/options that might or might not be needed.
If anyone wants to know my config, it's:

webpack.config.dev.js

export default {
  entry: { main: ['./src/index.js'] },
  plugins: [
    ...,
    new ReactRefreshWebpackPlugin()
  ],
  ...
}

babel.config.js (or .babelrc)

{
  ...
  plugins: [
    ...
    "react-refresh/babel"
  ]
}

package.json

{
  scripts: {
    dev: "webpack serve --hot webpack.config.dev.js",
    ...
  },
  devDependencies: {
    ...,
    "webpack": "^5.21.2",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  },
  ...
}

@pmmmwh
Copy link
Owner

pmmmwh commented Feb 9, 2021

There's no such thing as "webpack-dev-server@4.x"

There is this - it is in beta but it is quite stable as I recall from talking with maintainers of the project.

However, in cases where this is ambiguous we could only do a best guess, and in your case we received { main: {} } and after all the parsing and guessing we output the same thing. I guess we could do better by detecting this edge case (AFAIK only happens in Webpack 5 because Webpack 4 won't allow entry to be an empty object).

But when I added the proposed entry: { main: ['./src/index.js'] } config entry, it seems to have started working.
For Webpack 5 users, that's weird, because Webpack 5 guarantees everything working without any entry config.
You should update the README to reflect the requirement of having an entry: { main: ['./src/index.js'] } workaround for people that use Webpack 5 defaults.

This is a bug on our side - we have logic that would throw when we can't seem to search for the entry property but it is not properly exiting right now. We require the entry property because there is no means for us to guess how to inject entries for you via the plugin if it wasn't there. I would argue that it is always better to explicitly state where your entry point is for easier understanding of what is bundled.

Overall, the setup process is convoluted and ambiguous with all those variations of plugins/options that might or might not be needed.

I would like to know what we can improve on. HMR is inherently a very complex topic by nature and we try our best to encapsulate as much as possible while giving flexibility in the setup (like allowing multiple hot integrations). The Babel plugin is unfortunate as there are no reliable way to detect/inject a Babel plugin into your setup - we probably also don't want to do that either as there are community integrations like react-refresh-typescript. Other than that, I would assume in most cases you wouldn't need to touch any of the options (probably only the overlay.sockIntegration)?

@catamphetamine
Copy link

There is this

Oh, okay, there is webpack-dev-server@4.x then (in beta).

We require the entry property because there is no means for us to guess how to inject entries for you via the plugin if it wasn't there.

Why not simply default to src/index.js when no entry has been defined?

https://webpack.js.org/configuration/

"Out of the box, webpack won't require you to use a configuration file. However, it will assume the entry point of your project is src/index.js"

I would like to know what we can improve on.

Well, there's simply too much text. Too much variables, too much if/else-s. In this case do this. In that case do that. If you're using X do Y. If you're using Z do W. Too much variations. You prefer adding react-refresh/babel in webpack.config.js. I prefer doing that directly in .babelrc. You prefer doing isDevelopment && ... .filter(Boolean) magic. I prefer having a separate config file for each environment. You prefer adding HotModuleReplacementPlugin explicitly. I prefer specifying --hot flag instead. You may prefer webpack-plugin-serve or dev-middleware while I prefer webpack-dev-server. Do you see the issue? I do.

@pmmmwh
Copy link
Owner

pmmmwh commented Feb 9, 2021

Why not simply default to src/index.js when no entry has been defined?

I guess there is also the issue where you have defined it but we couldn't find it, or if your entry is injected by another plugin that runs afterwards. I think we could do that but would have to be pointed out in the docs that this is the behaviour.

Well, there's simply too much text. Too much variables, too much if/else-s. In this case do this. In that case do that. If you're using X do Y. If you're using Z do W. Too much variations.

Do you have concrete ways we can improve? What do you think we should do instead? Simply saying you need to add the Babel plugin to your configurations without providing examples? The examples you've raised are basically saying there are too many ways to configure Babel and Webpack. I agree a lot of the README is actually a tutorial on how to configure your Webpack setup instead of stuff related to this plugin, but given that this plugin also targets people who have no prior experience in Webpack and Babel (you will see this in the issues raised) and this complexity is a bit inherited from upstream I think it is inevitable?

You prefer adding HotModuleReplacementPlugin explicitly.

This is a special case - webpack-hot-middleware users needs this to activate HMR.

@catamphetamine
Copy link

I guess there is also the issue where you have defined it but we couldn't find it, or if your entry is injected by another plugin that runs afterwards.

Hmm, exotic edge cases. I don't know how you "search" for entry path, so I won't be able to further take part in this discussion. You should know better since you're clearly a more Webpack expert than I am. I have no interest in Webpack internals, just run my app and that would be enough.

Do you have concrete ways we can improve?

Well, ideally, it could have been an interactive configuration "quiz", something like: "Do you use webpack-dev-server or Y or Z? Answers: X, Y, Z, I don't know", and then "When using X, do you also use A, B, or C?", and then "Do you configure D through a separate config file or a webpack config file?", etc.
Too complicated, and I guess no one would ever create such thing.
Maybe it could be a set of "details"/"summary" items covering all possible cases, but then it would be a lot of those cases.
Or maybe something like:

What are you using?

webpack-dev-server

How do you configure Babel?

Through separate config

Do you use one webpack config or several?

One

Blah blah

Several

Blah blah

In webpack.config

Do you use one webpack config or several?

One

Blah blah

Several

Blah blah

Other thing
Another thing

Anyway, I'm not proposing a solution here, I'm just expressing the feelings of a regular user.

@avtpas
Copy link

avtpas commented Aug 3, 2021

Arent hot and hotOnly mutually exclusive?

nope, hot is for reload and hontOnly is for does not hard refresh (Browser) in case something happens.

They are actually mutually exclusive - webpack-dev-server internally would prefer one over the other I believe.

Also - I think target: 'web' would probably solve your issue too?

works for me ,thx

@MBelniak
Copy link

MBelniak commented Nov 16, 2021

Just in case someone comes across this one - in my case it was React Developer Tools extension not being installed in my browser.
Chrome: https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en-US
Firefox: https://addons.mozilla.org/en-US/firefox/addon/react-devtools/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search

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

No branches or pull requests

9 participants