-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
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
Vite injects css assets in wrong order with dynamic import and css modules. #3924
Comments
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
How did you solve it |
This comment was marked as spam.
This comment was marked as spam.
4 similar comments
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
Any updates?( Maybe @sodatea will provide some thoughts where to find problem in project and i will try to make pull request to vite? |
I'm seeing this issue as well, now that I've started to use storybook's new dynamic loading feature, my styles are broken in production stories. I've found that the css files are directly after the component in the network tab. So, in one example, I have a RadioButton component that imports Label (which has its own styles that I want to override), and then it imports some css module with the overrides. However, when building now, I see this: Which puts the RadioButton styles higher in the cascade, and they are overwritten by the Label styles, which is backwards from what I want. |
Here is a minimal stackblitz reproduction: https://stackblitz.com/edit/vite-gu874q?file=main.jsx vite: 2.7.1 |
Great work @IanVS! Really hope this helps resolving the issue. I would help, but have no idea on where to start unfortunately. |
I finally found the culprit, and FOR a while I thought My temporary solution is to load influenced page synchronously in router configuration. |
any idea when will #6301 be merged? |
As far as I know it's not ready, @mgiraldo. This is a sticky problem to solve. If you have any ideas or can help out, please do! |
i understand. thanks for all this work! |
I wonder whether Vite could maybe look for a With Webpack's Webpack Configuration
|
For those who (like me) had to ship and need a temporary workaround: Depending on your project, you may be able to use |
sadly this didnt work out for me @laurentvd 😔 i might need to refactor my components 🤔 |
I see the wisdom in Remix of having "per-page" css loaders in this case - JS imports and CSS cascade generally follow an inverse relationship, right? So the most correct CSS cascade will need about one CSS chunk per page.. |
I'm having related a related issue but perhaps also different? Every time I run vite build it slices all of the css code above the media queries in one of my components off. I checked the compiled css and half of that module is no where to be found. Any update on this? I tried disabling code splitting but it didn't seem to work, or perhaps my config file was wrong.. |
This seems to still be an issue. Really killing me. Any updates? |
is there any update on this? |
Applying styles in the wrong order is a deal breaker for using vite. |
Because it isn't fixed yet. Have you considered that this may be a difficult problem?
There are solutions to manage cascade order that do not depend on CSS order. Have you considered reading the thread that you're commenting on? |
Speaking of cascade layers, if you're using css modules (which is likely if you're hitting this issue), you could try out https://github.com/DefinedNet/postcss-assign-layer to assign all of your components to a separate layer from your global / utility layers. This doesn't work with the cascade layers polyfill, but I think browser support is good enough you shouldn't need the polyfill anymore. Another option for avoiding this issue is to not code-split your app. There are tradeoffs there, but it's something to consider. |
|
UPDATE: I just want to retract my addition to this issue. Mine was an embarrassingly newbie mistake of leaving a comment open >.< |
I've also encountered this issue as we upgrade a legacy project. The load order of CSS is important. Why is there no option to specify the order within the manifest.json? CSS order is, unfortunately, a real concern. Seeing how many people are interacting with this issue, I wonder why there hasn't been a solution proposed. |
I've got a really hacky solution in case it helps anyone, but it is very possible that it only works for my particular project: it consists of moving the styles from the <script>
document.addEventListener('DOMContentLoaded', function () {
const head = document.head;
const body = document.body;
const styleTags = head.querySelectorAll('style[type="text/css"]');
styleTags.forEach(function (styleTag) {
head.removeChild(styleTag);
body.appendChild(styleTag);
});
const linkTags = head.querySelectorAll('link[rel="stylesheet"]');
linkTags.forEach(function (linkTag) {
head.removeChild(linkTag);
body.appendChild(linkTag);
});
});
</script> However, keep in mind that in my project:
Also let me know if this is a terrible idea and why, please 🙏🏼 |
Still not a solution, but https://admin.defined.net uses https://developer.mozilla.org/en-US/docs/Web/CSS/@layer (finally part of the "Baseline") + https://github.com/DefinedNet/postcss-assign-layer to ensure our cascade is enforced programmatically. /* establish a layer order up-front, from lowest to highest priority */
@layer defaults, theme, libraries, patterns, components, utilities, overrides;
/** Defaults */
@import url('defaults.css');
/** Theme */
@import url('theme/colors.css');
@import url('theme/typography.css');
/** Patterns */
@import url('../../components/atoms/forms/border-focusable.css');
@import url('../../components/patterns/menus/menu.css');
/** Components are assigned by a PostCSS plugin for all `*.module.css` files */
/** Utilities */
@import url('utilities/layout.css');
@import url('utilities/color.css');
@import url('utilities/borders.css');
@import url('utilities/typography.css'); The PostCSS plugin rewrites all of our This still requires caution when it comes to specificity within each cascade layer, but it's much easier to avoid that. This enabled us to setup fully async react-router-dom routes, code-splitting our app finally! |
Hey want to get people's thoughts on the new React 19 docs, specifically this section, as it relates to this issue: https://react.dev/blog/2024/04/25/react-19?ck_subscriber_id=2099611990#support-for-stylesheets It looks like you can inline style sheets directly in the components, themselves, which unless I am mistaken, should solve pretty much everyone's issues here? Please correct me if I am wrong. Thanks. EDIT: Should have asked: "Does this solve all of the React users' issues?" |
I use svelte, so that doesn't help me. |
That's ok. Nobody's perfect |
Hey, is there any update on same? This issue is happening in latest vite version also with css module . ( when css code split is set to true) |
@jasikpark's workaround works in my build.
vite.config.ts import postcssAssignLayer from 'postcss-assign-layer';
//...
postcss: {
plugins: [
postcssAssignLayer([
{
include: '**/*.module.scss',
layerName: 'components'
}
])
]
}
//... Index.scss @layer base, components;
@layer base {
@import './scss/normalize';
@import './scss/variables';
@import './scss/fonts';
@import './scss/mixins';
@import './scss/globals';
@import './scss/typography';
} Router.tsx import { Suspense, lazy } from 'react';
import { createBrowserRouter, RouterProvider, LoaderFunctionArgs, Outlet } from 'react-router-dom';
const Home = lazy(() => import('../components/Home'));
const About = lazy(() => import('../components/About'));
export const Router = () => {
const routeConfig = createBrowserRouter([
{
path: '/',
element: (
<Suspense fallback={<div>Loading...</div>}>
<Home />
</Suspense>
)
},
{
path: '/about',
element: (
<Suspense fallback={<div>Loading...</div>}>
<About />
</Suspense>
)
},
])
return (
<RouterProvider
fallbackElement={<div>Loading...</div>}
router={routeConfig}
/>
);
} |
Hey @novym , will the above solution solve the order issue in same layer like component ? In my case I have 2 components module css which is not being imported in correct order. |
This was impacting our code as well, a react based app which uses Seems like a bug to me, CSS stylesheets should be appended to in the order that you reference/import them, right? If you import 'main_styles.css' right back at the start in the entry point, or reference it in your tag of a page, that should stay placed before anything else imported later on, in my opinion, and that seems to be the behaviour of HMR preview. At first my work around for this was basically to import the CSS for the global styles as 'inline', and add the styles to the page with a function that ensures the styles get placed before any other styles: import styles from "./../assets/css/styles.css?inline";
// Inject CSS styles into head before any other style elements.
function injectCSS(css) {
const styleElement = document.createElement('style');
styleElement.textContent = css;
const head = document.head;
const firstStyleOrLinkElement = head.querySelector('style, link');
if (firstStyleOrLinkElement) {
head.insertBefore(styleElement, firstStyleOrLinkElement);
} else {
head.appendChild(styleElement);
}
}
injectCSS(styles); Fixed the order of the only style sheet that was in the wrong placement. Very hacky solution though so I wasn't a fan of it. My new solution is to import our global style sheet before the per-component style sheet in every React component. import './../assets/css/styles.css';
import './../assets/css/components/ThisComponent.css'; And that seems to do the trick to ensure that the order of the styles is as each component expects, but has the downside of needing to import our CSS styles on every single component. Bit of a pain, but it seems to work at least. |
Looking into the issue... Can anyone provide a minimal reproduction of the bug on StackBlitz using the latest Vite? If anyone is experiencing this issue, please try checking if using https://github.com/privatenumber/vite-css-modules fixes the problem. |
Describe the bug
Vite injects css assets in wrong order with dynamic import and css modules.
Reproduction
Repo to reproduce
For example:
P.S. You can reproduce this but with cssCodeSplit: true or false.
System Info
Output of
npx envinfo --system --npmPackages vite,@vitejs/plugin-vue --binaries --browsers
:Used package manager:
Logs
Before submitting the issue, please make sure you do the following
The text was updated successfully, but these errors were encountered: