-
Notifications
You must be signed in to change notification settings - Fork 757
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
Add support for multiple require.context
with addition of useContexts
#1144
Conversation
Thanks @cymen, this looks really promising for the way I'm trying to split JS bundles by route, but still use server-side rendering. I ran into the same problem as #1034 where I couldn't use multiple files for SSR, even when I disabled sourcemaps. Here's a small example from my current setup, with a number of smaller split bundles. At the moment, because of the lack of SSR across all entry points, I've only split out components that I'm happy to be client-side rendered ( Beforeserver_rendering.js var componentRequireContext = require.context('components', true);
var ReactRailsUJS = require('react_ujs');
ReactRailsUJS.useContext(componentRequireContext); enquiry.js var componentRequireContext = require.context('enquiry', true);
var ReactRailsUJS = require('react_ujs');
ReactRailsUJS.useContext(componentRequireContext); search.js var componentRequireContext = require.context('search', true);
var ReactRailsUJS = require('react_ujs');
ReactRailsUJS.useContext(componentRequireContext); Afterserver_rendering.js var componentsRequireContext = require.context('components', true);
var enquiryRequireContext = require.context('enquiry', true);
var searchRequireContext = require.context('search', true);
var ReactRailsUJS = require('react_ujs');
ReactRailsUJS.useContexts([
componentsRequireContext,
enquiryRequireContext,
searchRequireContext
]); No changes to enquiry or search. I built a version of the package with your code, and I'm happy to say this lead to components from the Hey @BookOfGreg, hope you're doing OK! This is a pretty useful addition. 😃 |
README.md
Outdated
@@ -161,6 +161,8 @@ ReactRailsUJS.useContext(myCustomContext) | |||
|
|||
If `require` fails to find your component, [`ReactRailsUJS`](#ujs) falls back to the global namespace, described in [Use with Asset Pipeline](#use-with-asset-pipeline). | |||
|
|||
In some cases, having multiple `require.context` may be desired. If so, an array of `require.context` can be passed to `ReactRailsUJS.useContexts`. With an array of contexts, an attempt will be made to `require` the component from each context before falling back to the global namespace as described above. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide a more concrete example?
Or maybe point to an example in the codebase?
@cymen, thanks for your contribution. Sorry for the delays to get this merged and shipped. Looks useful! Please:
Thanks! |
@cymen, Do you have the availability to work on the changes suggested by @justin808? Please resolve the conflicts.
|
README.md
Outdated
@@ -161,6 +161,8 @@ ReactRailsUJS.useContext(myCustomContext) | |||
|
|||
If `require` fails to find your component, [`ReactRailsUJS`](#ujs) falls back to the global namespace, described in [Use with Asset Pipeline](#use-with-asset-pipeline). | |||
|
|||
In some cases, having multiple `require.context` may be desired. If so, an array of `require.context` can be passed to `ReactRailsUJS.useContexts`. With an array of contexts, an attempt will be made to `require` the component from each context before falling back to the global namespace as described above. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justin808 Had a go at adding a specific use case for multiple contexts, what do you think? @cymen not sure if there's a different example you had in mind.
In some cases, having multiple `require.context` may be desired. If so, an array of `require.context` can be passed to `ReactRailsUJS.useContexts`. With an array of contexts, an attempt will be made to `require` the component from each context before falling back to the global namespace as described above. | |
In some cases, having multiple `require.context` entries may be desired. In a larger application, you might find it helpful to split your JavaScript by routes/controllers to avoid serving unused components and improve your site performance by keeping bundles smaller. For example, you might have separate bundles for homepage, search, and checkout routes. In that scenario, you can add an array of `require.context` component directory paths via `useContexts` to `server_rendering.js`, to allow for [Server-Side Rendering](#server-side-rendering) across your application | |
```js | |
// server_rendering.js | |
var homepageRequireContext = require.context('homepage', true); | |
var searchRequireContext = require.context('search', true); | |
var checkoutRequireContext = require.context('checkout', true); | |
var ReactRailsUJS = require('react_ujs'); | |
ReactRailsUJS.useContexts([ | |
homepageRequireContext, | |
searchRequireContext, | |
checkoutRequireContext | |
]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the suggestion based on changes from my other PR to hopefully provide a clearer usage example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me (as mentioned elsewhere). Thanks for fleshing it out. I added another example use case with c5cd6c6 which is the one that sent me down this path of wanting multiple contexts (we've been using a forked version of react-rails in production for quite a while and it's been working well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really interesting to hear your use case for this.
@RiccardoMargiotta do you have time to push a new PR that includes your suggestions? |
@justin808 I've created #1221. Could you run the workflow please? |
@RiccardoMargiotta Thanks for pushing this forward. I didn't mean to disappear for a while. That documentation update looks good to me. |
No worries! As I said on the new PR, I'd be more than happy to continue on this feature on your existing PR here (but I couldn't work out a way to cherry-pick commits across forks, if that's even possible). Either way, I'm really excited that this is getting closer to a release, it'll be hugely helpful. |
@RiccardoMargiotta Sure, I'm happy to try -- I rebased my branch to master and cherry picked in your updates. I'm going to reread the documentation changes as the use case I wrote this for is slightly different so it might be useful to add another example there. |
Add additional use case for multiple require contexts to documentation.
Okay, I've updated the documentation for another use case -- it was a bit hard to condense the use case I wrote this originally for into a few sentences but hopefully it makes sense. @justin808 Can you run the workflow on this PR? |
Co-authored-by: Riccardo Margiotta <riccardo.margiotta@gmail.com>
Co-authored-by: Riccardo Margiotta <riccardo.margiotta@gmail.com>
Really interesting to hear your use-case for this, and great to know it's been working well in production for you for so long - definitely a good sign! Thanks for getting it all sorted on your original branch. I'm really looking forward to working with this on my app, glad I could help nudge it forward a little. What do you think, @justin808? |
|
@cymen It possibly got lost in the merge, but we're now missing line 9 of var constructorFromRequireContextsWithGlobalFallback = require("./src/getConstructor/fromRequireContextsWithGlobalFallback") Without this, we'll fail with:
|
|
@RiccardoMargiotta Oops, I think that did go missing in the merge. I've fixed that. I'll take a look at the merge conflict on the changelog. |
I took a look at adding testings -- I saw the For
For
I agree with @RiccardoMargiotta that is hard to know where to start. I also agree that there is very little risk because we're expanding the API by adding |
@cymen and @RiccardoMargiotta, should we merge? I can merge and put this into a 2.7 release. |
@justin808 Sure, I think it's ready. Thanks! |
@justin808 I'd be good with merging! Like Cymen, I've forked out my own version of the JS package with this change, and have been using it in production for a while. For my use case of route-based packs, it's been working great. |
Thanks @RiccardoMargiotta and @cymen! |
Thanks @justin808! Appreciate your efforts on this project. 👍 |
Summary
In some cases, it is desirable to be able to have multiple
require.context
and attempt to resolve in each before falling back to global. This PR addsuseContexts
(in the pattern ofuseContext
) which accepts an array ofrequire.context
and attempts to resolve the component/module in each context before falling back to global.Other Information
I was not able to get the test suite to run so I have not been able to add tests yet.