-
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
global-styles plugin doesn't work well alongside the sass-plugin #21079
Comments
Anyone? |
Do you have an example repository you could share? I wonder if it is maybe due to the processing that webpack is doing to your scss, and the way that it loads the style on the page. I'd have to see the actual data, though, in order to see what's happening. If you look here, you'll see that |
Hi Jeremy, Thanks for replying. Here's a small repro project I've just put together for this issue: https://github.com/fullofcaffeine/gatsby-global-scss-woes-issue-sample. You can see that the plugin config snippet for the I've followed the instructions in the When running, the markup generated by the Let me know if you have further questions. Thanks! |
Based on that information, it sounds like what I suspected. I think what is happening is that Can you dump the output from Another thing I might try is to convert the scss to css, and see if I'm at work right now, so I don't have a great deal of time to spend on this. I'll load up your repo later today and see if I can get it to cooperate. |
Another thing I just thought of is it's possible that the As long as you aren't importing this If all else fails, you might have to list the module as an external, so that webpack doesn't try including it into your final bundle. |
Thanks again for taking the time to look into it.
I actually suspected that, and I think that's what's happening. But I thought that these plugins were designed to be inter-operable/be used together. The fact that the docs for the global styles plugin doesn't mention anything about not working with the sass plugin made me conclude they were compatible, also because SASS is so popular and global styles is a very common approach that people coming from other static-site generators prefer to use. If that's the case, should this be considered a bug in any of the plugins and or Gatsby? I'll try the approach you suggested and post the results here. As a related note, the |
Is there a way to setup the
Would load the contents of I think this would be better than doing all the work of using |
I think it's more of a plugin incompatibility than it is a result of Gatsby's processing, or anything really pertaining to Webpack. From the way the documentation was written by the author of
I did a quick run of your repo, and below is the first few elements of the header components that are passed to JSON Output[
{
"key": "GlobalStyle1709833222",
"ref": null,
"props": {
"theme": {
"typography": {
"fontFamily": "Arial"
}
}
},
"_owner": null
},
{
"key": "TypographyStyle",
"ref": null,
"props": {
"typography": {
/** list of styles */
}
},
"_owner": null
},
{
"type": "meta",
"key": "4",
"ref": null,
"props": {
"data-react-helmet": true,
"name": "twitter:card",
"content": "summary"
},
"_owner": null
},
{
"type": "style",
"key": null,
"ref": null,
"props": {
"data-href": "/styles.943196fa3743f8c7b022.css",
"dangerouslySetInnerHTML": {
"__html": /** Looong list of bootstrap styles */
}
},
"_owner": null
},
] So, you can see that the issue is not caused specifically by Webpack not being aware of Gatsby, and you can also see that Gatsby is plenty aware of Webpack to handle this kind of scenario. The entire issue occurs because the plugin in question doesn't know how to handle The easiest thing to do at this point, if you don't want to handle reading/processing the scss yourself, is this: First thing, get rid of
This will import your stylesheet for side effects onto every page. The same general thing that the plugin was doing. This method just doesn't make it a React component. In
That's the most future proof method. However, you could also use Move that component up and you're done. The header for the bootstrap stylesheet looks like this: /*!\n * Bootstrap v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */ So long as you pick something to look for in that when matching your head components, you should be fine. In the end, my configuration looked like this: // gatsby-browser.js
import "./src/styles/style.scss";
// gatsby-ssr.js
export const onPreRenderHTML = ({ getHeadComponents, replaceHeadComponents }) => {
const headComponents = getHeadComponents();
for (const [idx, component] of headComponents.entries()) {
if (component.type === "style" && /^.*Bootstrap/mi.test(component.props.dangerouslySetInnerHTML.__html)) {
headComponents.splice(idx, 1);
headComponents.unshift(component);
break;
}
}
replaceHeadComponents(headComponents);
};
That might be something available in a Webpack plugin, or maybe in a babel plugin. Possibly even a combination of the two. You'd have to do some research. |
While that is the easiest method, it probably isn't the best method. You lose control over your style component, and have to rely on some arbitrary string matching in order to wrangle it again. The ideal method, if you're dead set on using scss, would be to process it yourself, and load it how you want to into the head. I wouldn't even rely on a third party plugin to do it for me. I would use |
Okay, I've got an even better method, where you can use this global styles plugin with scss flawlessly. After further investigation, I realized it's not specifically an issue with the plugin not being able to process scss. It's that the scss So, you were on to something when you asked about a way to have webpack insert the data into a variable. I had completely forgotten about Webpack's inline loaders 🙄. Make your import { createGlobalStyle } from '@nfront/global-styles';
import globalStyle from '!css-loader!sass-loader!./style.scss';
const GlobalStyleComponent = createGlobalStyle`
${globalStyle[0][1]}
`;
export default GlobalStyleComponent; And it works flawlessly. The magic happens here: In a normal loader, you would then pass the data from [
[
loader chain,
data,
""
]
] We only have one component, so we pick the first index, then we pick the second index to grab the data. That's what gets passed to |
Oh wow, thanks a bunch for the elaborated responses!
I don't get this part. How's Webpack aware of Gatsby and vice-versa? Is there any glue code for that? So you mean that this code:
Is added by Webpack? In that case, why can't I just reorder it then using the
Thanks for suggesting this, but I agree with you that's it's too error-prone. Might bite me back after a while.
I actually started with this approach when I saw your last reply :) May I ask how you trigger
Thanks! I didn't have a chance to try this one out yet, but I'll do soon. Seems like the best way to go, indeed. On a related note: I must say though, I'm really surprised such a simple thing - deciding the loading order of assets - can be so complex in Gatsby. I think the Webpack solution you showed above is fine, but it's far from obvious and it requires the use of another plugin. It'd be really nice if Gatsby provided a way to fallback and allow users to manually and easily change the order of assets. At first, I thought that by copying the Just a small rant in hope that the core team might discuss and improve that part of Gatsby ;) Other than that, I'm enjoying it. |
It's true that Webpack is not aware of Gatsby, but what I meant here is that that was not the problem. Gatsby is aware of Webpack (but that wasn't the issue, either) because the framework that is used to call the API endpoints in Check out the static-entry source. It is what Gatsby feeds Webpack to start the generating process, so when it gets sourced, it is essentially running all of that code, and hitting those endpoints from within Webpack's runtime, and using Webpack's own stats and chunks files to keep track of where everything is landing.
You certainly can. You just have to go through the process to find the chunk that was added to the head. That's basically what I was doing in the "easy" method, even though it turned out to not be the easiest 😆
Considering the fact that Gatsby is pluggable, and any of those plugins are capable of hooking into the Gatsby lifecycle, and updating various
I could see maybe being able to tell it general groups of what to load... like "load plugin styles first", and "load generated static styles second", then "load css-in-js styles", etc. But then, you'd still have plugins that interact with other things the wrong way, so an overarching distribution like that wouldn't work for everything, therefore, you'd still need that little loophole that lets people put things where they want for their plugin... which means you have to let the end-user do the same thing... and we're back at square one. It's not so complex when you have a simple (non-gatsby) site building with webpack, because resources get loaded in the order they are encountered, and there is far less interactions/hooks. In that case, it certainly is easier. But, the complexity of anything that has any depth will always grow as it becomes more and more robust. It's my opinion that the Gatsby team has done a fantastic job of making it as easy as possible for consumers to use the tool. Please do let me know if we've solved your issue when you've had a chance to do some testing. |
Yes, it works! Thanks a lot for guiding me through it. Your replies were all detailed and helpful. It's been some time since I got such quality responses from an open-source community. I really appreciated that!
Yeah, looks like this was an unfortunate consequence of the abstractions Gatsby provides out-of-the-box. It's dead simple and works for 80% of the time, but can be very confusing and problematic for the other 20%, specially when it comes to plugins that can or may interact (or when users expect them to interact). Anyway, at least people with similar issues will probably hit up on this issue, and there are several approaches to try here ;) Cheers! |
I ended up abandoning this approach. The main problem is that it's harder to configure postcss as part of the inline configuration and honestly, I was tired of so much work for so little gain. The culprit here is the The solution I found was to effectively use I don't find much value in tweaking the typography.js settings using its js API, the main value I get from it are the themes that help me to quickly bootstrap with pretty typeface styles. |
Ah, yeah, I can see that being a pain. Just a couple more ideas:
With both of these, there would be no need for |
Hi! I have the same issue with using Bootstrap. I'm struggling to put together the right setup based on your explanations. I think using @fullofcaffeine do you have an updated version of your example repo with the pipeline you ended up using? and maybe including the suggestions @Js-Brecht made in their last comment? Cheers! |
The build step is placing the contents for the `global.scss` after the component styles. That is preventing component styles to overwrite some of the selectors set on `global.scss` such as the grid ones. References: - https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/#onPreRenderHTML - gatsbyjs/gatsby#21079 (comment)
Summary
I'm trying to use the
gatsby-plugin-global-styles
to re-order the css link tags so they come before the style tag added bygatsby-plugin-typography
, but it seems they don't play along well (or maybe I'm missing something?).I followed the instructions but when I import the
scss
file, something in gatsby (I couldn't find out what yet) just injects them to the bottom of the header tag, always. It doesn't matter if I use this plugin or try to re-order the typography header component ingatsby-ssr.js
. So, my sass styles are loaded lastly (in this caseBootstrap 4
) and they end up breaking the typeface styles fromTypography.js
.I also added the
gatsby-plugin-global-styles
configuration snippet below the one forgatsby-typography
, as instructed by the docs here, and as you may see below.Environment (if relevant)
System: OS: Linux 4.15 Linux Mint 18.3 (Sylvia) CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz Shell: 5.1.1 - /bin/zsh Binaries: Node: 10.14.1 - ~/.nvm/versions/node/v10.14.1/bin/node Yarn: 1.12.3 - /usr/bin/yarn npm: 6.4.1 - ~/.nvm/versions/node/v10.14.1/bin/npm Languages: Python: 3.6.5 - /home/myuser/.pyenv/shims/python Browsers: Chrome: 79.0.3945.88 Firefox: 72.0.1 npmGlobalPackages: gatsby-cli: 2.8.27 gatsby-plugin-typography: 2.3.21
File contents (if changed)
gatsby-config.js
:package.json
:gatsby-node.js
: N/A (empty)gatsby-browser.js
: N/A (empty)gatsby-ssr.js
: N/A (empty)Thanks in advance.
The text was updated successfully, but these errors were encountered: