Webpacker: Regression: Webpacker HMR causes SSR to fail in Webpacker 4+

Created on 5 Jul 2019  路  18Comments  路  Source: rails/webpacker

https://github.com/reactjs/react-rails/issues/985

In webpacker 3 with HMR server side rendering worked for components marked "hot"
In webpacker 4+

ExecJS::ProgramError in Adviser::AmlChecks#new
Showing app/views/welcome/index.html.erb where line #1 raised:
ReferenceError: window is not defined
(execjs):35:1
(execjs):24679:14
global ((execjs):1:102)
Object.<anonymous> ((execjs):1:120)
Module._compile (module.js:653:30)
Object.Module._extensions..js (module.js:664:10)
Module.load (module.js:566:32)
tryModuleLoad (module.js:506:12)
Function.Module._load (module.js:498:3)
Function.Module.runMain (module.js:694:10)

Most helpful comment

I'm having the same issue. I just update from webpacker 3.5 to 4 and having issue with window - ReferenceError: window is not defined

All 18 comments

Also related PR on open project:
https://github.com/mberlanda/cheidelacoriera/pull/57

I don't think HMR & SSR are intended to work together. Can you tell me more about how you expect this to work?

HRM is supposed to no-op with SSR.
The issue is a component may be marked "hot" for client-side but also be pre-rendered.
This will be the same file that worked in Webpack/er3 but not Webpack/er4.

Do you mean hot in the webpack sense or the SSR sense?

webpack: hot components are loaded via socket by the HMR script injected into
SSR: hot components are chunks loaded via import() in the pre-rendered js.

Webpack sense. Didn't know about the other one, or always assumed they were the same.

Something is referencing window, which does not exist in SSR-land. Before, you may have had a library that shimmed window in if it did not exist. Like this: https://github.com/reactjs/react-chartjs/issues/57#issuecomment-271106746

I could not find an off-the-shelf solution, this outdated project is the closest to what I was looking for. I would not go this route, instead, try and find which component is calling window so that you can re-work it to be isomorphic.

Can you show me the html that this file would output: https://github.com/mberlanda/cheidelacoriera/blob/master/app/views/welcome/index.html.haml

I'm having the same issue. I just update from webpacker 3.5 to 4 and having issue with window - ReferenceError: window is not defined

@jakeNiemiec I'm still running into this issue. I think either:

  1. This issue should be re-opened.
  2. We should open an issue in another library if the problem is there.

Starting in webpacker 4, something is referencing window without checking if it's defined. I don't have any idea where to look for that though.

Starting in webpacker 4, something is referencing window without checking if it's defined.

HMR _(streaming modules to the browser to be executed by browser)_ is pretty antithetical to SSR _(executing modules on the server so that the browser doesn't have to do it)_. The code for HMR requires window. I don't know how you can even get around that.
image

I'm still running into this issue....I don't have any idea where to look for that though.

What do you use for SSR? Can you disable it during development?

So it worked in Webpacker 3 and HMR also worked in webpacker 3.
Basically you wrap it in an if window and disable it for SSR.
The problem is Webpacker seems to do it when included without it even needing to be invoked meaning it can't be wrapped externally.

Webpacker can't control what Webpack has in their codebase. Webpacker currently does not have any references to window in the codebase.

I am pretty sure it can be done. @justin808 uses both of these in his project. eg: https://github.com/shakacode/react_on_rails/pull/1156 You might take a look at that, I have only heard good things about it.

I'm going to be making a bunch of updates to react_on_rails very soon. We've got things working great with:

  1. SSR -- Server Side Rendering
  2. Dynamic code splitting with SSR (that one is a bit tricky)
  3. HMR

I'm not clear on why there's a connection with SSR and HMR.

With React on Rails, SSR is done by either

  1. Reading a bundle made just for SSR
  2. By hitting the webpack-dev-server and getting the same bundle the client uses.

I've never seen number 2, using the same bundle, in real production system as you can't have animations, window, etc. used when rendering.

What do you use for SSR? Can you disable it during development?

I'm using react-rails. I could disable it for development, but if I ever pull in a package that references window, I won't know that it's going to break until I deploy to production.

I'm not clear on why there's a connection with SSR and HMR.

There's no connection between SSR and HMR. They're two entirely separate features that people want. It's just that you can't currently use them together (at least with react-rails, I haven't tried react_on_rails).

I would expect HMR code to no-op if window is undefined. That seems reasonable to me, though I have no idea about the difficulty of fixing webpack to do this.

I didn't know that there were no references to window in this project. Thanks for pointing us to the real problem--I think this issue can remain closed.

I would expect HMR code to no-op if window is undefined. That seems reasonable to me, though I have no idea about the difficulty of fixing webpack to do this.

I don't think that's a webpack issue.

HMR works fine for window.

It's SSR that doesn't work. Code needs to be structured so that it doesn't depend on window during SSR.

I just did some experiments with React on Rails.

React on Rails can pull the server bundle from webpack-dev-server.

If react-hot-loader is installed, then the bundle has React code that accesses window

ERROR in SERVER PRERENDERING
Encountered error: "ReferenceError: window is not defined"

I think the solution is to ensure that the server rendering file is created differently than the client bundle file and thus not provided by the webpack-dev-server.

@justin808 I use react-rails and have this issue. Only thing that i didn't tried so far except disabling hmr was react-hot-loader. If i understand you correctly, removing that module from everywhere will make it work.

Will give it a try.

Just checking in. Does anyone have any updates on this issue or have found a workaround?

Sorry moved comment about workaround to original Issue on react-rails)

Was this page helpful?
0 / 5 - 0 ratings