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

[Question] How to enable Server side rendering with Webpack externals from Sprocket #2085

Closed
zocoi opened this issue May 7, 2019 · 6 comments

Comments

@zocoi
Copy link

zocoi commented May 7, 2019

Hi

I have a legacy React app which uses react-rails and require React via Sprocket, React is available as window.React on the client side. When we add new UI features and pages, we decided to use webpacker and have React available from global externals. Here's our environment.js

const { environment } = require('@rails/webpacker')
const typescript = require('./loaders/typescript')

environment.loaders.prepend('typescript', typescript)

environment.config.merge({
  externals: {
    jquery: 'jQuery',
    react: 'React',
    'react-dom': 'ReactDOM',
    // react_ujs: 'ReactRailsUJS',
  },
})

module.exports = environment

However, this approach doesn't work with server-side rendering because React is not available. I tried to add react to package.json and in server_rendering.js but it doesn't seem to help

const react = require('react')
var componentRequireContext = require.context('components', true)
var ReactRailsUJS = require('react_ujs')
ReactRailsUJS.useContext(componentRequireContext)

Any help is appreciated, thank you.

PS: SSR only needs React not jQuery and the error was ExecJS: ReferenceError: React is not defined

@zocoi
Copy link
Author

zocoi commented May 7, 2019

cc @BookOfGreg to see if he has any insight

@BookOfGreg
Copy link
Contributor

I wonder how having that externals statement affects how webpack works...
Could you change your webpack back to default and see if it now serverside renders? It's expected that this will break client-side but that's fine as this is an experiment; A default webpack with react-rails should successfully work.
If that is the case then you wonder if we need 2 separate webpacks for the 2 pack files, or someone who is much better at webpacker than me can tell you how to magically do it via external in one and node_modules in the other.
If it doesn't work even then then the problem is likely your environment or code and not webpacker; have you gotten the react-rails example running serverside? Perhaps start there and port your things into it until it breaks.

@zocoi
Copy link
Author

zocoi commented May 7, 2019

thanks @BookOfGreg for the suggestion, I tried that first and ran into a different issue (on the client side like you said), the SSR works really well. I can see the DOM in "View Source". However, all the CSS were messed up during hydrating due to React being loaded twice and generated different class names. Also the React duplication error suggestion was shown.

That's why I tried webpack externals next and it works well for client side until SSR is needed. If server_rendering.js was run with ExecJS + node, I wonder why explicitly require react there doesn't work

Re: 2 separate webpacks for the 2 pack files, I have no idea how to set that up

@BookOfGreg
Copy link
Contributor

Perhaps an issue on Webpack itself would help summon someone who knows how to manage externals in that way.
For now one suggestion would be instead of loading react from the global namespace via externals. Could you bundle react with your webpack and add yours to the window namespace instead?

@justin808
Copy link
Contributor

@jakeNiemiec @gauravtiwari we should probably start closing some of these issues to cut down the number of open issues.

The solution to this question is that SSR requires a different webpack config so that there are no references to things like window as SSR is executed on the server where there is no window.

@jakeNiemiec
Copy link
Member

@justin808 I agree, but I try to be very carful with which issues I force-close. I have been on the receiving-end of an issue purge. The end result was many new issues based on old issues without the context of the previous conversation.

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

4 participants