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

Server-side rendering is not working with sprockets-rails 3.0 #443

Closed
oleglitvin opened this issue Jan 16, 2016 · 53 comments
Closed

Server-side rendering is not working with sprockets-rails 3.0 #443

oleglitvin opened this issue Jan 16, 2016 · 53 comments

Comments

@oleglitvin
Copy link

In sprockets-rails 3.0 Rails.application.assets is disabled when config.assets.compile=false (rails/sprockets-rails#220).
And React::ServerRendering::SprocketsRenderer is failing on production environment at this line, with undefined method '[]' for nil:NilClass

@oleglitvin
Copy link
Author

OK, there is an opened pull-request https://github.com/reactjs/react-rails/pull/430/files

@rmosolgo
Copy link
Member

Could you give that branch a try? Let me know if it works for you -- it looks good to me but I'd like a second opinion before I merge it!

@inchr
Copy link

inchr commented Jan 18, 2016

I need this too :( I will test your PR very soon @rmosolgo ! Thanks for your work!!

@DTwigs
Copy link

DTwigs commented Jan 18, 2016

This would be super helpful!

@rmosolgo rmosolgo mentioned this issue Jan 22, 2016
17 tasks
@oleglitvin
Copy link
Author

Could you give that branch a try? Let me know if it works for you -- it looks good to me but I'd like a second opinion before I merge it!

@rmosolgo yep, it works!
Sorry, it doesn't, I forgot to enable server side rendering.

@oleglitvin
Copy link
Author

It fails at this line https://github.com/reactjs/react-rails/pull/430/files#diff-543f6fa05678c006b8d4baa5cd4b517cR13, not being able to find react-server.js (even if react-server was added to the config.assets.precompile and being precompiled)

@djforth
Copy link

djforth commented Jan 29, 2016

+1

1 similar comment
@dbackeus
Copy link
Contributor

dbackeus commented Feb 4, 2016

+1

@rmosolgo
Copy link
Member

rmosolgo commented Feb 4, 2016

Could you try react-rails 1.6.0? It includes #430 which was my first try at fixing this

@tirdadc
Copy link

tirdadc commented Feb 5, 2016

I can confirm that I have this issue in production with 1.6.0 when server-side rendering is used.

ActionView::Template::Error (No compiled asset for react-server.js, was it precompiled?):

@rmosolgo
Copy link
Member

rmosolgo commented Feb 5, 2016

Ok, thanks, let me try to track that down!

@rmosolgo
Copy link
Member

rmosolgo commented Feb 5, 2016

Ohh strange. When it creates the manifest, the manifest has production/react-server instead of react-server. Then, SprocketsRenderer fails to find react-server since it has a different logical path.

I found a workaround:

  1. Add a JS file, server_rendering.js

  2. Make sure server_rendering.js is compiled (Rails.application.config.assets.precompile += %w( server_rendering.js ))

  3. Add to server_rendering.js:

    //= require react-server 
    //= require components
    // Require everything needed for server rendering 
  4. Specify only server_rendering.js for server rendering:

      config.react.server_renderer_options = {
        files: ["server_rendering.js"], # files to load for prerendering
      }

This way, it bundles react-server into server_rendering.js, it doesn't look it up when you try to render a page!

I'll look for a proper fix tonight or tomorrow!

@dudeman
Copy link
Contributor

dudeman commented Feb 19, 2016

We didn't want the react-server code to end up in the components.js since that's delivered to browser clients. So we created a components-server.js file containing:

//= require react-server

And then added that components-server.js file to the server_rendering_options:

config.react.server_renderer_options = {
    files: ["components-server.js", "components.js"], # files to load for prerendering
  }

This seemed to fix the prerendering asset location error above. However, we then were getting an error because of an additional sprockets 3 incompatibility. PR for that is here #478

@oleglitvin
Copy link
Author

It seems that #471 fixes this issue. The only thing that needs to be done is to add server_rendering.js to the Rails.application.config.assets.precompile list.

@rmosolgo
Copy link
Member

Maybe i should add that to rails generate react:install, but add --skip-server-rendering if you don't want the JS manifest & initializer

@oleglitvin
Copy link
Author

Sounds good)

andrewpatterson3001 added a commit to andrewpatterson3001/action-cable-chat-second-attempt that referenced this issue Feb 22, 2016
@alcedo
Copy link

alcedo commented Feb 29, 2016

i'm using gem 'react-rails', "~> 1.6.0" but am still encountering the above error. eg:

http://cl.ly/1m2y3B1N3f1j

any ideas?

@rmosolgo
Copy link
Member

This patch isn't merged yet because it'll be a breaking change.

Did you try the workaround described here? #443 (comment)

@alcedo
Copy link

alcedo commented Mar 1, 2016

Updates: ok ive tried the above workaround but it doesnt seem to work. I've also tried some workaround on my own, ie: http://cl.ly/2c3O3s343Y3k but to no avail too.

I've also upgraded to gem 1.6.1

@rmosolgo
Copy link
Member

rmosolgo commented Mar 1, 2016

doesnt seem to work

Can you elaborate? For example, did you get an error? What was the message & stack trace?

Also, did you restart your development server after changing the configurations?

@benben
Copy link

benben commented Mar 3, 2016

The workaround didn't help me either.

2016-03-03T19:42:59.810190+00:00 app[web.1]: Completed 500 Internal Server Error in 13ms (ActiveRecord: 0.6ms)
2016-03-03T19:42:59.812302+00:00 app[web.1]:
2016-03-03T19:42:59.812312+00:00 app[web.1]: ActionView::Template::Error (No compiled asset for react-server.js, was it precompiled?):
2016-03-03T19:42:59.812313+00:00 app[web.1]:     33:   %fieldset.form__fieldset
2016-03-03T19:42:59.812314+00:00 app[web.1]:     34:     %legend.form__legend
2016-03-03T19:42:59.812314+00:00 app[web.1]:     35:       Releases
2016-03-03T19:42:59.812316+00:00 app[web.1]:     36:     = react_component 'MultiFieldForm', {parent: 'system', component: 'Release', fields: @system.releases.to_json}, { prerender: true }

@rmosolgo
Copy link
Member

rmosolgo commented Mar 3, 2016

Weird! It shouldn't even be looking for react-server anymore since we override that value with

  config.react.server_renderer_options = {
    files: ["server_rendering.js"], # files to load for prerendering
  }

😿

@rmosolgo
Copy link
Member

rmosolgo commented Mar 3, 2016

@benben
Copy link

benben commented Mar 3, 2016

just to be clear: I put the config.react.server_renderer_options in my application.rb

@tirdadc
Copy link

tirdadc commented May 22, 2016

Confirming that the workaround works with 1.7.1.

I tried to get a component that uses moment.js in its getInitialState() to pre-render once I set this up and also added //= require moment to server_rendering.js, but I still got an error:

Encountered error "ReferenceError: moment is not defined" when prerendering Calendar

Anything else I need to do to get that to work?

@alcedo
Copy link

alcedo commented May 23, 2016

hmm did u put //= require moment above your component definition? some code samples might be useful

@krazyjakee
Copy link

Does server_rendering.js go in /assets/javascripts/server_rendering.js?

We're getting...

ActionView::Template::Error: No compiled asset for server_rendering.js, was it precompiled?
No compiled asset for components.js, was it precompiled?

@alcedo
Copy link

alcedo commented May 24, 2016

@krazyjakee did you add server_rendering.js into the asset precompile list?

@krazyjakee
Copy link

@alcedo yes, it is definitely there.

@alcedo
Copy link

alcedo commented May 24, 2016

@krazyjakee

my server_rendering.js goes into /assets/javascripts/server_rendering.js

and this is the content of it, if its of any help.

//= require react
//= require react-server
//= require react_bootstrap
//= require components

@krazyjakee
Copy link

@alcedo mine was...

//= require react-server
//= require react_ujs
//= require components

I'll tweak it and get back to you. Thanks!

@alcedo
Copy link

alcedo commented May 24, 2016

no problem. and i think you probably wont need react_ujs, since its only used on client side.

@rafavalerio
Copy link

Did the workaround!

But now I get the same error with server_rendering.js

RuntimeError (No compiled asset for server_rendering.js, was it precompiled?):

Rails 4.2.6
ruby 2.3.1p112
sprockets 3.6.2
react-rails 1.8.0

@rmosolgo
Copy link
Member

To confirm, did you add server_rendering.js to your list of precompiled assets, something like

Rails.application.config.assets.precompile += %w(server_rendering.js)

?

@rafavalerio
Copy link

Yes! Did all the steps you provided!
It's strange because it works in development mode and worked in production until some days ago. And it seems a lot of people is having the same issue. Perhaps any conflict with other dependency gems?

I'm still trying to find out!

@rmosolgo
Copy link
Member

until some days ago

woah, how strange?! did anything else change in your app at that time?

@rafavalerio
Copy link

I'm trying to figure out! Looking through the commits, updated some code and added only a few gems, but nothing related to React itself.
Added pundit gem and pointed another one (validates_cpf_cnpj) to a Github fork repo.

But I don't believe these changes are related with this rendering issue.

@JoelBeasley
Copy link

@rafaelv90 I'm experiencing the same thing, worked fine in production, still works in dev but today stopped working in production.

@rmosolgo
Copy link
Member

rmosolgo commented Jul 5, 2016

stopped working in production

was it after a redeploy? or, it just started 💥ing while running?

@JoelBeasley
Copy link

JoelBeasley commented Jul 5, 2016

@rmosolgo after redeploy. I have 2 production servers, one I use as staging. When I pushed up to staging it broke today. When I push the existing working production server code to staging (an exact production replica) it starts throwing the "was it precompiled" error.

@rmosolgo
Copy link
Member

rmosolgo commented Jul 5, 2016

Is the diff for that redeploy small enough to list the changes? For example:

  • Any gem updates?
  • Ruby version update?
  • Application code update?
  • Application configuration update?
  • Server administration changes?

@JoelBeasley
Copy link

JoelBeasley commented Jul 5, 2016

@rmosolgo The production code mirrored on staging worked, my mistake was viewing the log, it was a process of the prior build, learned something new about EY.

I also found that when deploying on EngineYard the assets won't re-precomplie if the assets.rb is changed, only if the assets .js/.css are changed, or its in the EY config to always precomplie.

Solution that worked for me
Adding the assets to the precomplie, then touching the .js asset allowed it to precomplie and work.
Rails.application.config.assets.precompile += %w( react-server.js components.js )

Unfortunately I was not able to locate the differences that suddenly required the react-server.js components.js to be listed in the precomplie, I did check the gemlock files of both codebases and they are identical.

@rmosolgo
Copy link
Member

rmosolgo commented Jul 5, 2016

Thanks for sharing your findings!!

@maveonair
Copy link

I can confirm that I only had to add Rails.application.config.assets.precompile += %w( react-server.js components.js ) in config/initalizers/assets.rb to get server side rendering work on Heroku.

@dimoreira
Copy link

Guys, in my scenario I use separated manifest files for loading dependencies and react components for main interface and admin interface.

My files are divided as following:

application.js:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require maskedinput
//= require jquery.fancybox
//= require getstream
//= require react
//= require react_ujs
//= require react-rails-hot-loader
//= require components

server_rendering_components.js:

//= require react
//= require react-server
//= require components

components.js:

//= require accounting.min
//= require moment-with-locales.min
//= require autosuggest
//= require_tree ./react

moment.locale('pt-br');

admin.js:

//= require react
//= require react_ujs
//= require react-rails-hot-loader
//= require admin_components

server_rendering_admin_components.js:

//= require react
//= require react-server
//= require admin_components

admin_components.js:

//= require_tree ./admin-react

config/environments/{development.rb,production.rb}"

config.react.server_renderer_options = {
    files: ['server_rendering_components.js, server_rendering_admin_components.js']
  }

config/initializers/assets.rb:

Rails.application.config.assets.precompile += %w( admin.js admin.css server_rendering_components.js components.js server_rendering_admin_components.js admin_components.js )

I just keep getting this error:

React::ServerRendering::PrerenderError - Encountered error "ReferenceError: ReactDOMServer is not defined" when prerendering ComponentName

What I'm doing wrong?

@dimoreira
Copy link

Nevermind guys, I just fix the files object to correction:

Instead of:

config.react.server_renderer_options = {
    files: ['server_rendering_components.js, server_rendering_admin_components.js']
 }

Corrected for this:

config.react.server_renderer_options = {
    files: ['server_rendering_components.js', 'server_rendering_admin_components.js']
 }

@rmosolgo
Copy link
Member

rmosolgo commented Dec 9, 2016

Sounds like we have a couple of options here. Soon I'll merge #471 and remove the confusing defaults. Thanks for sharing your solutions!

@rmosolgo rmosolgo closed this as completed Dec 9, 2016
C-Higgins referenced this issue in C-Higgins/Go May 3, 2017
abhchand added a commit to abhchand/reely that referenced this issue Feb 19, 2020
Fixes run time bug where react components won't load with 500 error

Solution taken from: reactjs/react-rails#443 (comment)
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