-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Global javascripts #2039
Comments
I have found that this works very well, see here for details: #1944 (comment) See here for deeper discussion: #1835 |
Just to add to this discussion a bit late: It's a good recommendation from @jakeNiemiec; loading lazy chunks on-demand on a per-view basis is one way to go. The split chunks optimization is also still effective, I believe, for your use case @lukaszwnek. You get the benefit of better caching, since webpack will separate out vendor modules into shared chunks, and, if you're using an HTTP/2-enabled CDN, better parallelization across the added bundles for downloading content. The problem you've described is something I think Webpacker should help handle. As it stands now, developers have to come up with a way to ensure a single *_with_chunks_tag is used. The way I've solved this is with some extra helpers that allow you to "add chunks" to the module MyWebpackerHelper
def add_javascript_packs(*packs)
@additional_javascript_packs ||= []
@additional_javascript_packs += packs
end
def add_stylesheet_packs(*packs)
@additional_stylesheet_packs ||= []
@additional_stylesheet_packs += packs
end
def javascript_packs
["global"] + (@additional_javascript_packs || [])
end
def stylesheet_packs
["global"] + (@additional_stylesheet_packs || [])
end
end <!-- app/views/layouts/application.html.erb renders each "*with_chunks_tag" once -->
<%= stylesheet_packs_with_chunks_tag *stylesheet_packs %>
<%= javascript_packs_with_chunks_tag *javascript_packs %> <!-- app/views/posts/show.html.erb modifies the "*_packs" lists -->
<% add_stylesheet_packs "data-table %>
<% add_javascript_packs "data-table" %> Another helpful change is to set environment.splitChunks((config) => ({...config, ...{ optimization: { runtimeChunk: 'single' }}})) Hope that's helpful. |
@rossta This is a response to both issues.
From the docs:
If we continue to that page, we see:
All of the above is in preparation to address this:
You aren't wrong in this solution, but it looks like you are doing more work than you need to be. It also cuts against the grain of both tree-shaking and splitChunks (as evidenced by micromanaging the runtimeChunk). Let's move this out of the esoteric realm and into the practical. I can illustrate this specifically if you can post an example repo containing this or a static profile file from this (run webpack with these flags |
Ok! I'm going to capture a few key points then we can move to https://discuss.rubyonrails.org.
I've been using this repo as a resource to help explain concepts to folks. The master branch is a vanilla Rails 6 app with Webpacker. There are many example branches that I use to illustrate or demo fix and changes for specific concerns. Feel free to create a branch or use an existing one such as this https://github.com/rossta/rails6-webpacker-demo/compare/example/react-multi-pack off of which to base discussion. The repo is already set up with the webpack bundle analyzer and that branch is in a state to show a before/after of splitChunks optimization for an app with multiple entry points.
Let's discuss the benefits/tradeoffs of both approaches. I agree with the benefits of lazy chunking (I've been advocating for them for a while) though they may require developers to consider async loading UX. Multple entrypoints may be more work in some ways, but they are also more consistent with what Rails developers have been using in Sprockets.
Just a quick point on this: the default Webpacker config overrides the webpack default by applying optimization to 'all' chunk types, including initial chunks. webpacker/package/environments/base.js Line 138 in 6779013
I think you and I are well-equipped to answer to these concerns and prescribe some patterns that would best serve the Webpacker community. I believe it's common for Rails developers to make certain assumptions about how things work in Webpacker (or expectations about how things should work) coming from the Rails asset pipeline. I've witnessed code- and bundle-splitting done wrong time and again with Webpacker so it would be great to have a set of examples to illustrate proper execution. |
Is there any reason against making This would be the easiest way imho.. All other ways are much more complex and I really don't see any benefit of having |
@h0jeZvgoxFepBQ2C I would gladly support a PR in this fashion in the interest of improving developer ergonomics. Looks like several promising solutions to the original issue have been posted. |
Hi! First of all, thanks for this awesome tool.
I'm currently in the middle of upgrading from version 3 to 4 and bumped into the following problem.
Before the upgrade I had a Rails layout file which included a "global" pack using:
<%= javascript_pack_tag "global" %>
This pack included all the javascript that is used across all our views. Specifically, the layout file has a top bar menu with some JS dropdowns and whatnot. This global pack handled all that shared code. Then, every time we had some additional javascript that we needed, we would add it in the Rails view file (rendered within the layout file):
<%= javascript_pack_tag "data-table" %>
Not all views rendered within this specific layout had those additional packs, some of them were static Rails pages.
Now, while doing the upgrade, I wanted to start using
splitChunks
as a replacement for the deprecatedCommonsChunkPlugin
. Here's my current setup:The thing is, I can't figure out how to proceed with this "global" pack I had before. If I add this:
<%= javascript_packs_with_chunks_tag "global" %>
to the layout file, I can't have the second<%= javascript_packs_with_chunks_tag "data-table" %>
in my view file, as this duplicates the chunks (as stated in the README). I tried pushing it all to the view file, but then I have to make sure I have ajavascript_packs_with_chunks_tag
in all view files (even those static ones) and we have a lot of those. This doesn't feel right, as it creates a lot of duplication just to handle some javascript components from the layout file.I also tried
javascript_packs_with_chunks_tag
in the layout andjavascript_pack_tag
in the view when I need it, but this apparently doesn't execute the pack from the view file.I thought about having only a single pack, including it using
javascript_packs_with_chunks_tag
in the layout and using webpack's dynamic imports to import the additional packs for specific views (e.g. based on the URL). This, however, requires quite a lot of changes, so wanted to confirm that's the only way before digging into that. Am I missing something? Is there a better way of handling this scenario?Thanks again
The text was updated successfully, but these errors were encountered: