The dir '/dist/styles' disappears after 'yarn start', but is present after 'yarn build'. Why?

All was described here: The dir '/dist/styles' disappears after 'yarn start', but is present after 'yarn build'. · Issue #2071 · roots/sage · GitHub
And I received an answer, but I don’t understand it. Could someone help me and explain my issue?

The issue:
A few days ago all was Ok. Now if I run ‘yarn build’ all is Ok, but if I run ‘yarn start’ I haven’t the dir ‘/dist/styles’. Screenshot: Screenshot by Lightshot
There aren’t any error messages.

The answer:
The styles are injected by the Webpack build process (HMR). That’s why the directory is missing. So this is by design. This means you should only be using the proxy URL (i.e. localhost:3000) during dev.

But I use the proxy URL localhost:3000: http://prntscr.com/jine6w
Where I’m wrong?

Looks like site blink (I see content) and then a half sec later I have a blank page.

I gotta dash, but since I put time into this, here is my half-baked answer:

So your issue is only happening during development (yarn start). Sage uses Webpack for it’s development build/watch process. A feature of Webpack is called Hot Module Replacement, which “exchanges, adds, or removes modules while an application is running, without a full reload.” Your styles are considered to be a module. So when it detects a change, it will get the new styles. However, it doesn’t compile a new stylesheet.

The 404 error is expected when HMR is running. This is where the “styles” that HMR is injecting are:

You’ll also notice the hot updates that HMR is receiving:

Perhaps, the best way to understand this is to simply obeserve it in action. Run yarn start, open up dev tools and watch what is happening to the stylesheet reference at the end of the head and the hot updates in the network tab when you make a change to the stylesheets.

Related:

2 Likes

If you are having other issues, then the missing stylesheet isn’t the problem. I made a troubleshooting guide for issues like this:

Thanks for explanation. Now all is clear and I much more understand behavior of Sage9.

Actually at the moment I found a js bug in my code. I think it’s the cause of my troubles (the content placed outside of the viewport). It remains to understand why after ‘yarn build’ all looks good. I guess I was confused 404 for main.css and I thought that is root of problem.

Any way, thanks for help!

If you have a bit time maybe you could say me why after ‘yarn build’ #site-header height is 80, but after ‘yarn start’ the same js code gives 5000? And as result margin-top: -5000px; It makes me crazy.

JS code: http://prntscr.com/jiq903

Probably because jQuery is calculating the height of that element before styles have been injected (when using yarn start), when it has a very very large height (caused by all sorts of possible things). The simplest solution is to set your header’s height in CSS instead of detecting it after load with JavaScript. The issue you’re seeing is probably caused (this time) by style injection, but it could happen “in the wild” for other reasons (slow or bad transfers, etc). IMO detecting dimensions with JavaScript isn’t super reliable: it’s better to set them in CSS if you can.

3 Likes

Generally, I agree with you (I always prefer CSS vs JS), but I guess it’s very wrong behavior when the one code gives a different result. Just imagine something like that: x=2+3; // 5, but in other run: // 5000 :slight_smile:

Yes, looks like jQuery is calculating the height of that element before styles have been injected. But either I need use JS another way (so, I’m wrong and don’t know something important) or it’s the problem of Sage9. All CSS styles load before JS (they placed in the footer), so I can expect that my JS take right height after styling. There are many situations where we could need in JS the right styles of DOM element.

Correct me if I wrong.

CSS loaded from a remote file is render-blocking, so in most real-world situations the CSS is loaded before JS fires. When yarn start inserts styles, they are not render-blocking because they are inserted via JavaScript. This means that they may not be fully loaded when your jQuery runs, regardless of where you’ve placed it on the page.

Your JS as written executes only once, on the initial page load, which means that it has only one chance to get the height of your element. This prevents it from getting the correct height in the above scenario, but would also prevent getting the correct height in other situations, i.e. if a user resizes the window in such a way as to change the height of the element you’re measuring. You may be able to address your issue (and other hypothetical situations causing sizing to break) by attaching your size-calculation code to an event that watches for something relevant, i.e. you could hook it to the resize event, or possibly use the Mutation Observer to directly observe your root element, and trigger the measurement JS when it changes size.

I don’t understand what exactly it is you’re trying to accomplish in terms of styling, so I can’t suggest a pure CSS alternative, but I’ve had pretty good look over the last several years sizing headers and page content without the use of JS.

1 Like

Thanks for reply & explanation.