Skip to content

Issues working with Webpack Dev Middleware in server rendering environments #36

Closed

Description

@manuelbieh

Hey,

I'm not sure if this has to do with this Webpack plugin or with Webpack itself, with Webpack Dev Middleware and in general, I'm not even sure if this makes sense at all.

I've just spent two hours to get this really great plugin working in a custom Server Side Rendering environment that's currently using Webpack Dev Middleware (WDM) as Webpack's dev server and Webpack Hot Middleware (WHM) for HMR.

The issues I encountered:

  • While my actual server rendered application is served on localhost:8500, my WDM is running on port 8501, but the socket connection is always created for window.location.port and is not configurable (yet)
  • After I manually changed the port to 8501 in runtime/createSocket.js, it's still not working. There's an outgoing request to http://localhost:8501/sockjs-node/info?t=1579726105901 but it looks like WDM isn't listening to a /socksjs-node/info route: Cannot GET /sockjs-node/info
  • POST /sockjs-node/213/kxx15upe/xhr_streaming also gives me a 404
  • Universal components that are also used on the server side fail because $RefreshSig$ is not defined, which seems obvious because they are only defined when we're in a browser environment.:
ReferenceError: $RefreshSig$ is not defined
    at eval (webpack:///./src/shared/i18n/IntlProvider.tsx?:17:10)
    at Module../src/shared/i18n/IntlProvider.tsx (build/server/server.js:5202:1)

The last one makes sense but maybe we could just assign () => {} noops to global.$RefreshSig$ and global.$RefreshReg$?!

After all, I'm not really sure if this plugin does even make sense in universal rendering scenarios. If it does, I'd be happy to get some helpful hints how this could be integrated into my certainly little bit unusual but probably not that exotic setup.

// edit:
current state of my implementation attempt can be found here:
https://github.com/manuelbieh/react-ssr-setup/compare/feature/react-refresh

Activity

  1. changed the title [-]Issues working with Webpack Dev Middlewaren in server rendering environments[/-] [+]Issues working with Webpack Dev Middleware in server rendering environments[/+] on Jan 22, 2020
  2. Ephem commented on Jan 23, 2020

    @Ephem

    @manuelbieh I'm also interested in this, but don't have time to dig into your project in detail (and am no expert on react-refresh-webpack-plugin either), so I thought I'd ask something that got me curious. 😄

    The implementations I've seen for HMR/Refresh with SSR comes down to only using it for the client, and having other solutions for the server (such as the delete require.cache[...] on every request trick). Is this the approach you are taking? If so, does this line only apply to the client build, or have you added the babel plugin for the server as well? I guess that could be related to the last issue you mention?

    I think #10 might be related to some of the socket issues you are having?

    I've tried adding this plugin to a SSR-project as well, not including the babel-plugin in the server build, and the issues I got (so far) were all related to this plugin not supporting the webpack-(dev/hot)-middleware yet.

  3. manuelbieh commented on Jan 23, 2020

    @manuelbieh
    Author

    Same here. No time. Yesterday it was a "let's see how far I can get within a 2 hours timebox" kind of thing.

    The line you linked to, yes, I'm currently using the same babel config to transpile both the client and the server build. I was also thinking about splitting it up and use different configs for both builds but that was a task that would have taken too long to fit into my timebox 😉

    I will now put this "on hold" for a while because, as @pmmmwh said on Twitter: I think after addressing a lot of the issues with customisability this might solve itself though.

    I don't need to have this very urgently, it's more a nice to have for me so I won't invest any more time for now. Will probably revisit this issue in ~4-5 weeks, maybe the issue really is no issue anymore then.

    If you solved it in an SSR scenario or wanna discuss potential solutions, just send me a DM, I'm happy to discuss! 😉

  4. ianvieira commented on Feb 10, 2020

    @ianvieira

    I had the same problem with the $RefreshSig$, in the end, it was caused by the cache-loader. As my client build runs before the server one, my server was using the cached version to the client.

    To avoid it, check if you have any cache that can be shared between the two compilers (as cache-loader or babel-loader cache).

  5. Ephem commented on May 11, 2020

    @Ephem

    This was solved by the v0.3 release for me.

    I use dev- and hot-middleware in a custom SSR-setup which previously did not work, but by following the Readme and using this config everything now works out of the box:

    new ReactRefreshWebpackPlugin({
      overlay: {
        sockIntegration: 'whm',
      },
    }),
    
  6. pmmmwh commented on Jun 8, 2020

    @pmmmwh
    Owner

    This should be resolved by #102.

  7. donaldpipowitch commented on Jul 28, 2020

    @donaldpipowitch

    Looks to be back in 0.4.1?

      ERROR in Template execution failed: ReferenceError: $RefreshSig$ is not defined
      
      ERROR in   ReferenceError: $RefreshSig$ is not defined
    

    0.4.0-beta.5 works for me.

  8. pmmmwh commented on Jul 28, 2020

    @pmmmwh
    Owner

    Looks to be back in 0.4.1?

      ERROR in Template execution failed: ReferenceError: $RefreshSig$ is not defined
      
      ERROR in   ReferenceError: $RefreshSig$ is not defined
    

    0.4.0-beta.5 works for me.

    How does your setup look like? Did you allow the react-refresh/babel to parse files that is not being processed by the plugin? What version of Webpack/React/React-Refresh are you on?

    The runtime in 0.4.0 rewrites all calls to $RefreshSig$ and $RefreshReg$, so seeing an error related to $RefreshSig$ probably means that either the file didn't get picked up by the plugin, or our runtime have something horribly wrong in it (which could happen too).

    The repo that this issue was originally created with runs well (I've pulled and updated dependencies to test). Most likely a configuration issue?


    On this topic, I would be very grateful if someone can put together a bare-bones vanilla React SSR example - not only to showcase how it should be configured, but it can also be used as a regression test case.

  9. andriichern commented on Aug 26, 2020

    @andriichern

    I hope this would be helpful for other people who faced the same issue with ReferenceError: $RefreshSig$ is not defined error.

    For me it was OK durig development and I caught an error during production build running.

    After debugging my configs I can say for sure: it is mandatory to set NODE_ENV value explicitely in your scripts before running webpack.

    Why it is mandatory?
    According to docs, configuring react-refresh we have a check for env in babel config: !api.env('production') in case of separate babel conf and
    const isDevelopment = process.env.NODE_ENV !== 'production';
    ...
    plugins: [isDevelopment && require.resolve('react-refresh/babel')].filter(Boolean) in case of inline babel conf.

    Without setting explicitely NODE_ENV you've got undefined value for NODE_ENV thus your checks always results in false and you're always adding react-refresh/babel into babel plugins.

    And unfortunately we cannot rely on webpack's configuration mode here. According to their docs setting up mode configures DefinePlugin, but it is accepted during build process itself, but during configs loading and reading it's not set yet thus we get undefined.

    So, use explicit NODE_ENV=production webpack... or NODE_ENV=development webpack... in your package.json scripts.

  10. akphi commented on Aug 26, 2020

    @akphi

    @andriichern I think there's a simpler way if you're referring to being able to find the right environment during loading the Webpack config (See their example at the bottom of this guide)

    module.exports = (env, argv) => {
      const isDevelopment = argv.mode !== 'development';
      ...
  11. pmmmwh commented on Aug 27, 2020

    @pmmmwh
    Owner

    After debugging my configs I can say for sure: it is mandatory to set NODE_ENV value explicitely in your scripts before running webpack.

    I'm sorry that the examples mislead you a bit. What I really want to illustrate is that it is a good idea to only use development plugins in development, and you can have your own means to detect that. In that sense, setting NODE_ENV is necessary if it is your means of determining whether we are going to produce a development build. However, you can also use Webpack's mode argument or even split configs to achieve the same result.

    I'll update the new docs in #189 to better illustrate this concept.

  12. andriichern commented on Sep 17, 2020

    @andriichern

    @blacksteed232 It seems that argv would be present only if you pass a cli arguments like --mode development, but I could mislead smth

  13. andriichern commented on Sep 17, 2020

    @andriichern

    @pmmmwh Absolutely agree with you)

    What I tried to say in my commnet is that provided configurations' exmaples are not incorrect. Its just an additional 'trick' or mandatory step to have a possibility to distinguish dev build from prod right inside config files. And I had separate prod/dev configs with mode options setup correctly - and that was not the case of mine.

    I've faced with issue like that for the first time and want to share my experience (and probably help) for similar issues. And I'm sure its not a problem in plugin/plugin dev team :)

    Moreover thank you for doing such good things for all of us!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions