Skip to content

Copyless setup of react source #254

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

Merged

Conversation

byroot
Copy link
Contributor

@byroot byroot commented Apr 28, 2015

Copying files on boot is really problematic, especially in capistrano scenario where the application run under a different user than the one compiling assets.

e.g. the deploy user compiles the assets and the rails user can only read them.

The current copying behaviour requires a lot of capistrano hacks, and is also unsafe because the running application if compromised could corrupt the asset bundles.

My proposal is not to copy files but to append different directories to sprockets search path. To work, this would require to change the paths in the react-source gem to:

  • build/JSXTransformer.js
  • development/react.js
  • development-with-addons/react.js
  • production/react.js
  • production-with-addons/react.js

@rmosolgo thoughts about this?

cc @gmalette

@facebook-github-bot
Copy link

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla - and if you have received this in error or have any questions, please drop us a line at [email protected]. Thanks!

@rmosolgo
Copy link
Member

😹 The same idea hit me while writing up #252 , I love it.

It looks like this removes support for the "enviroment drop-in path" and that's fine with me -- seems like a rare use case with a trivial workaround of just dropping a copy of react.js in your /assets/javascripts/vendor directory (whatever pleases you)

You'll probably have to update a couple tests, too. Thanks, this is awesome!

@byroot
Copy link
Contributor Author

byroot commented Apr 28, 2015

I'm glad you like it. I'll update the test and PR the related change to react-source

@rmosolgo
Copy link
Member

Oh I missed the changes to react-source. If you don't feel like altering react-source, I'm open to a rake update_react task that updates the gem, then copies the those files into the react-rails source.

So then to add different versions, you'd just add different react-rails asset paths to the sprockets environment (instead of react-source paths).

Your call, I love the copy-free setup either way

@byroot
Copy link
Contributor Author

byroot commented Apr 28, 2015

I already started a PR on react-source, and it feels like the cleanest solution anyway. I'm no grunt expert though so it's not easy :p

byroot added a commit to byroot/react that referenced this pull request Apr 28, 2015
byroot added a commit to byroot/react that referenced this pull request Apr 28, 2015
byroot added a commit to byroot/react that referenced this pull request Apr 28, 2015
@facebook-github-bot
Copy link

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks!

@byroot
Copy link
Contributor Author

byroot commented Apr 28, 2015

So @rmosolgo, On second though the rake task is probably simpler and do not require to release react-source nor to break it's compatibility.

So I pushed 8e16728 that does just that. The same tests are still broken, but I'll see what I can do to fix them.

@zpao
Copy link
Member

zpao commented Apr 28, 2015

👍 I was going to ask in the other PR about compatibility.

The other option we have here is to stop using react-source entirely. I don't know how useful it actually is at this point. When I first started this project I modeled it after a couple other things (combo of coffeescript and ember) but didn't know the implications.

What we do with pyreact is actually just download the js files from https://github.com/reactjs/react-bower into that repo and then there aren't the constraints of another dependency. If there's no value in react-source, then I'm happy to just kill it, let me know.

@byroot
Copy link
Contributor Author

byroot commented Apr 28, 2015

Well, actually I moved react-source as a development dependency only since It's not needed at runtime anymore.

So yes using the same strategy than pyreact sounds good. I'll do that then, it will simplify even more.

@byroot byroot force-pushed the dont-crash-on-boot-because-of-file-copying branch 3 times, most recently from 1311f96 to c2106b5 Compare April 28, 2015 19:02
@byroot
Copy link
Contributor Author

byroot commented Apr 28, 2015

Ok, so I vendored everything using bower. I also fixed the "environment drop-in path" test case (the rails app assets directories have priority over the gem).

There is 2 remaining broken test cases, but I don't really understand them. @rmosolgo your help would be appreciated to figure out what wrong with thoses.

@byroot byroot force-pushed the dont-crash-on-boot-because-of-file-copying branch from c2106b5 to 390c0db Compare April 28, 2015 19:09
@byroot
Copy link
Contributor Author

byroot commented Apr 28, 2015

Ok, so out of the 2 failures, one already fail on master for me, so it must be a problem with my setup.

As for the second one (drop-in files), I think I already cover that in another test. The coverage lost though is the test that assert that the development version is served. Not sure if it's critical.

@rmosolgo
Copy link
Member

How does this work with a new project?

If it's a new project, lib/assets/react-source/ would be empty, right? So adding those directories to the asset pipeline wouldn't be much help. I'd rather not make a new user run a rake task just for setup (that would bring back the file copy problems).

I see that lib/assets/react-source is gitignored, but what if we actually committed that to the repo and distributed it in rubygems? In fact, I think we could commit that instead of vendor/react, since the gem doesn't depend on those files.

That way, the rake task would be part of react-rails maintenance. To update the vendored JS, you'd run the task, which:

  • gets the latest from bower into git-ignored directories
  • copies versions into lib/assets/react-source (or wherever)

This introduces a hidden dependency on bower, but hey I guess that's the downside of this approach. Worth it IMO.

What do you think of that? Have I missed something?

@byroot
Copy link
Contributor Author

byroot commented Apr 29, 2015

If it's a new project, lib/assets/react-source/ would be empty, right?

Not sure what you mean by that. lib/assets/react-source/ stays in the react-rails gem, not in the hosting app. But whatever since your next point is good.

I think we could commit that instead of vendor/react, since the gem doesn't depend on those files.

That's a good point and it also fix one issue I have with the current state of the PR, which is that you can't use it as a git gem because the files are created during the build.

I'll update this PR in a minute. Hang on.

@byroot byroot force-pushed the dont-crash-on-boot-because-of-file-copying branch from bd8dff7 to c7c5c63 Compare April 29, 2015 18:03
@byroot
Copy link
Contributor Author

byroot commented Apr 29, 2015

@rmosolgo should be good now.

The rake react:upload task will update react to the latest released version and copy files in the proper place.

@byroot byroot force-pushed the dont-crash-on-boot-because-of-file-copying branch from c7c5c63 to 7f84c44 Compare April 29, 2015 18:08
@byroot byroot force-pushed the dont-crash-on-boot-because-of-file-copying branch from 7f84c44 to 07eec91 Compare April 29, 2015 18:10
@byroot
Copy link
Contributor Author

byroot commented Apr 29, 2015

For the record as just tested this branch in my app as a git gem, and it dies work as intended.

@rmosolgo
Copy link
Member

That looks nice! Bower is just the means for getting those files into the right directories. Then, the Railtie switches on config.react.variant and adds the desired directory to the asset pipeline.

The only remaining thing is this: is there any test that the directory approach really works? Eg testing production vs. development, testing add-ons vs no add-ons? (I'm not 100% sure how to test it)

This removes support for environment-based drop-in react.js files but that's OK with me. I've never heard anyone using that configuration. I'll create a changelog after this PR is merged.

@byroot
Copy link
Contributor Author

byroot commented Apr 29, 2015

The only remaining thing is this: is there any test that the directory approach really works?

It's really hard to test since sprockets caches everything. But I can give it a try.

On a side note. It seems that the path is appended too late. I tried deploying 07eec91 and assets:precompile is failing in production:

TypeError: can't modify immutable index
.../shared/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/index.rb:81:in `expire_index!'
.../shared/bundle/ruby/2.1.0/gems/sprockets-2.12.3/lib/sprockets/base.rb:109:in `append_path'
.../shared/bundle/ruby/2.1.0/bundler/gems/react-rails-07eec911ed95/lib/react/rails/railtie.rb:39:in `block in <class:Railtie>'

I'll find a way to fix this.

@rmosolgo
Copy link
Member

Not sure if this is related, but it rings a bell: #241

@byroot
Copy link
Contributor Author

byroot commented Apr 29, 2015

260cb28 fixed it. It's just that sprockets freeze it's environment on after_initialize.

I successfully deployed 260cb28 in production.

@byroot
Copy link
Contributor Author

byroot commented Apr 29, 2015

Grumble. Of course that change broke the same tests again....

I'm quite busy today, but I'll fix the tests as soon as I have a bit of time.

@rmosolgo
Copy link
Member

@byroot I tried another way of adding those assets, and I also added a test for the precompile task (only makes sure no 💥), here's a PR into your branch: byroot#1

Almost there!

byroot added 2 commits April 29, 2015 23:56
…e-copying

fix(Railtie) add asset paths another way, add test for precompiling assets
@byroot
Copy link
Contributor Author

byroot commented Apr 30, 2015

f5e47ed fixes the new precompile test under 3.2.

@byroot
Copy link
Contributor Author

byroot commented Apr 30, 2015

And 1c92a45 test that it's the development version that is loaded. I don't know How I could assert that different settings load different version since it would require to reboot rails :/

Would that be good enough for you?

@rmosolgo
Copy link
Member

rmosolgo commented May 1, 2015

👍 from me! I'll give it a try locally before I merge it and let it hang here for a bit in case anyone else has suggestions.

@rmosolgo
Copy link
Member

rmosolgo commented May 4, 2015

I gave it a try locally:

  • pointed at

      gem 'react-rails', #  '~> 1.0'
        github: "byroot/react-rails",
        branch: "dont-crash-on-boot-because-of-file-copying"
  • tried getting :development and :production variants locally

  • at first, I had trouble -- even after changing to :production, I was still getting the development version

  • I cleared my sprockets cache (manually deleted tmp/cache in my case), then it worked:

    image

👍

@byroot
Copy link
Contributor Author

byroot commented May 4, 2015

Oh the cache issue is interesting, I totally didn't think about it.

It's probably a minor issue, but quite annoying. What we could do is to append the react-rails settings to the sprockets environment version: https://github.com/rails/sprockets-rails/blob/656c9d266a0c5d29d19c566831c8d7daa2f2005d/lib/sprockets/railtie.rb#L91-L97

@byroot
Copy link
Contributor Author

byroot commented May 4, 2015

I think byroot@b3ee527 would solve the issue. Let me know if you want it included in this PR.

@rmosolgo
Copy link
Member

rmosolgo commented May 4, 2015

would be nice as a separate PR!

On Mon, May 4, 2015 at 2:16 PM, Jean Boussier [email protected]
wrote:

I think byroot/react-rails@b3ee527
byroot@b3ee527
would solve the issue. Let me know if you want it included in this PR.


Reply to this email directly or view it on GitHub
#254 (comment).

rmosolgo pushed a commit that referenced this pull request May 5, 2015
…e-copying

Copyless setup of react source
@rmosolgo rmosolgo merged commit 67e8ffa into reactjs:master May 5, 2015
@rmosolgo
Copy link
Member

rmosolgo commented May 5, 2015

what a huge win, thanks @byroot 🎊 🎉 !!

@byroot
Copy link
Contributor Author

byroot commented May 5, 2015

My pleasure :)

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

Successfully merging this pull request may close these issues.

4 participants