-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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 assets to entries sorted according to their dep graph. #8092
Conversation
|
||
return { | ||
js: stats.assets.js.filter(isNotRootAndMatchesPage), | ||
css: stats.assets.css.filter(isNotRootAndMatchesPage), |
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.
i removed the sort
by preload because it's not always stable :/ so messes up the order
}) | ||
|
||
if (groups[chunkName]) { | ||
Object.entries(groups[chunkName].childAssets).forEach( |
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.
it is very unclear when this is populated, iv'e tried a bunch of import()
calls to stuff and never seen this have anything in it..
|
||
const webpackStats = { | ||
...jsonStats, | ||
assetsByChunkName, |
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.
idk if this is still needed
12a7a55
to
88a281c
Compare
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.
Thanks for the PR, per usual :) From what I can tell, this looks good, but I'm going to ask a few questions so I can make sure we're on the same page.
I'll probably want to pull this down and write some tests against it to validate.
Speaking of... the unit tests in Travis are failing, so those are probably worth looking into.
@pieh want to weigh in here?
as="script" | ||
rel={script.rel} | ||
key={script.file} | ||
href={`${__PATH_PREFIX__}/${script.file}`} |
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.
Does script.file
=== script.name
here? Why the switch?
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.
I'm presuming it's because you changed the algo in assetsForCurrentPage()
so it's returning a slightly different structure?
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.
I moved some of the work that was done here to the stats plugin, which creates an asset object like: { file, chunkName, rel }
, file felt more descriptive i guess esp, next to the added "chunkName".
chunk. Thus topological sorting orders chunks from bottom-layer chunks to | ||
highest level chunks that use the lower-level chunks. | ||
*/ | ||
module.exports = (chunks, chunkGroups) => { |
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.
100% out of scope, but I wish we could create a utility containing this algo, and then have both us and html-webpack-plugin use it 🙃
} | ||
|
||
apply(compiler) { | ||
compiler.hooks.done.tapPromise( |
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.
So this was tapAsync
previously, now tapPromise
?
I'm not a webpack guru, so not sure if it it's a meaningful difference 🤷♂️
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.
same thing, the only difference is you can use a promise instead of a callback, which is more inline with what we do elsewhere
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.
Didn't look closely enough to see if it was a refactor or a straight copy 🙃 Makes sense!
// Add <link>s for styles that should be prefetched | ||
// otherwise, inline as a <style> tag | ||
headComponents.push( | ||
...styles |
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.
Overall, what you're doing here is pushing non-prefetch elements to the start of the array, then everything else, correct?
What if we re-wrote this slightly for clarity (or at least I think it's clearer), e.g.
const prefetchedAssets = styles
.filter(s => s.rel === `prefetch`)
.map(style => (
<link
as="style"
rel={style.rel}
key={style.file}
href={`${__PATH_PREFIX__}/${style.file}`}
/>
))
const nonPrefetchedAssets = styles
.filter(s => s.rel === `prefetch`)
.map(style => (
<style
key={style.file}
data-href={`${__PATH_PREFIX__}/${style.file}`}
dangerouslySetInnerHTML={{
__html: fs.readFileSync(
join(process.cwd(), `public`, style.file), 'utf8'
)
}}
/>
))
headComponents.unshift(...nonPrefetchedAssets) // this clarifies things a bit, i.e. that these are first
headComponents.push(...prefetchedAssets)
) | ||
}, | ||
}, | ||
new StatsExtractorPlugin(), |
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.
I like this change a lot! Extracting to a separate file is a nice win.
yeah i've been meaning to fix the tests, just wanted to get some feedback first before workin on it |
fc4ca3e
to
2116fff
Compare
80f3bfe
to
6436ce9
Compare
6436ce9
to
6f7c669
Compare
updated, rebases and fixed tests. Anyone want to take a chance on this ;) I could use the fix :0 |
I've spent a bit more time on this and i've got a few questions...why are we auto sorting the inline styles before everything? Consider linking font-awesome and bootstrap.css, we definitely want those to show up first, before any app styles. At the moment that's pretty hard to do without implementing |
Hmm yeah I was looking at this earlier (using the demo repro at #6302) and noticed similar. Do you have time to make a basic repro site using plain CSS and |
yup should have a moment today to do it |
err, a quick try didn't have much luck. This is pretty hard to reproduce on a simple site. Reasons, i think, because there isn't enough complexity in the css requires, and this issue is sort of by definition non-deterministic... |
Here's a kinda demo that shows the auto-sorting inlining styles resulting in different styles being applied in gatsby develop vs gatsby build. https://github.com/m-allanson/gatsby-v2-css-ordering. It doesn't demo the main issue that you're fixing though. Edit: pushing all the styles straight to headComponents will fix the behaviour in the above demo. |
People use CSS still??? :-P |
another data point, i've got this in react-bootstrap as a hacky plugin and it seems to work great: https://github.com/react-bootstrap/react-bootstrap/tree/master/www/plugins/gatsby-plugin-sorted-assets |
and here is a great example of how it was broken prior: https://5ba00f734ed62f7dda3cf9e5--react-bootstrap.netlify.com/components/badge/ |
Any updates here? Going to try the aforementioned plugin in the meantime—currently blocking a launch for me. |
#8560 possibly related. also several others issues with other weirdness of styles popping up this week. |
If it helps, I've also seen this issue, similarly as described by @topherauyeung:
This is the same for me, when I go to non-homepage links directly, the styles are wonky. HOWEVER (possibly the helpful part) When I hover over a Feel free to take a look at a live version of this behaviour here: https://chrisfrew.in/getting-started-in-2018-with-magento-apache-and-php/ just hover the mouse over anywhere on the top of the post to see the styles injected (white background should go to gray, code highlights work, etc) |
@frewinchristopher can see it even clearer in yours—thanks for sharing. |
we've had to resort to not using |
I left a detailed comment on issue #9911 mentioning how I reproduced this issue along with a repository & live demo of the issue. It's very similar to @frewinchristopher's description of the improper styles loading and taking precedence when a link is being hovered over. |
I think the Gatsby link issue is slightly different than what is being solved here. That problem is that the resources for each page are not the same as what's needed for the next navigation. From what i can tell when you hover a link it preloads the next page's assets. However in the case of CSS, that's likely to include a bunch of styles that are already loaded, e.g. global site styles. The problem with this is it realllly messes with the cascade since files that are supposed to loaded first are being loaded again after more specific styles. this doesn't always work well. What should happen is that Gatsby should only load new style resources, not all resources for the page. @pieh as far as you know does that describe the current behavior of gatsby-link, and the page resource pipeline as a whole? |
@jquense Agreed this PR is not solving the issue I was experiencing—meant to add that explanation to my comment @ #8092 (comment). I thought it was happening on load and not just after hovering a gatsby-link at some point, but as of now it's only the latter.
I think that's correct. I thought I could get around this by importing global styles to Off the top of my head, other ways to fix might be 1. doing whatever happens in dev because it doesn't happen there 2. disable css prefetching (or make it disable-able). |
We don't inject same styles again. This is different problem - see #9911 (comment) ---edit: |
@pieh Did you get a chance to check out my repro repo? https://github.com/dustinhorton/marketing Just realized the docs (https://www.gatsbyjs.org/docs/creating-global-styles/) still recommend loading global styles in the layout component, if it exists—I could revert to that. |
yeah, i think i had noticed tho that the way webpack splits css chunks with the SSR setup you get a lot duplication across chunks. e.g. the stylesheet is different (page--foo, page--bar.css, etc) but much of the content is the way. Might need a more aggressive splitChunks setup perhaps? |
any chance we could merge this? I relize it may not solve all the problems but it definitely solves some of them. I'm tired of copying this plugin into every site i build :P |
I would love to see this merged too. Seems like it's affecting several people. I just tried rebasing it and it rebased cleanly against |
For what it's worth, I have a workaround for the time being, which is simply loading any custom CSS from
Make sure your style file(s) are in your |
This PR has gotten in a pretty gnarly state, and I think it's extremely plausible that it's not needed with #11072. As such--let's close this out. If I'm off base or if this is still worth re-visiting, let one of us know or re-open and we'll take another look. As always, thanks @jquense for the PR. Sorry this didn't get merged! |
hmm #11072 seems like a worse solution to this? This is already a solved problem webpack html plugin does this and its what most apps use as a default. not splitting css seems like a worse default. |
also this handles js assets as well, which should also be sorted and included in the right order |
@jquense let's revisit this, then. When you get a minute, want to fix up the merge conflicts? Otherwise I'm happy to do this later, as well. |
ya definitely i'll take some time to clean it up 👍 |
Hi @jquense! We are going through old PRs with the core team. We really appreciate this contribution and we would like to have it in the Gatsby repo eventually. However, as there haven't any activity with the branch lately, we are going to close it. Feel free to reopen it when you get the time to fix the merge conflicts. Thank you so much for your contributions and looking forward for more of them. 💜 💪 |
i've published a hacky third party version at: https://www.npmjs.com/package/gatsby-plugin-sorted-assets Ya'll sorry i haven't had time to update this! I probably won't have more time in the near future but i do want to nominate this issue as something that the team should explicitly mark as needed. The current way gatsby handles adding css assets is broken, and perhaps the severity of it is offset by folks using css-in-js solutions, but topo-sorting the css files is essentially required for css-modules at least, and is way |
Sadly, @jquense the plugin doesn't seem to work with gatsby@^2.15.15 :( |
This
stealsborrows the chunk sorting algo from html-plugin. At the moment assets are included in sort of a random order which doesn't work for css especially. There is a bunch here that i'm a little iffy on but in my tests it seems to work...