remix
remix copied to clipboard
CSS bundle contents are tree-shaken when re-exporting a component/module
What version of Remix are you using?
1.11.1
Are all your remix dependencies & dev-dependencies using the same version?
- [X] Yes
Steps to Reproduce
Re-export a component that imports a .css.ts
file.
Expected Behavior
Styles should be included in the css bundle.
Actual Behavior
Styles are ignored, and not included in the css bundle.
Thanks for the bug report. I've reproduced the issue — even in our dev
branch which now marks all Vanilla Extract files as having side effects, which I thought might have fixed this issue too.
I've also been able to reproduce the same issue with CSS Modules and CSS side-effect imports, so this impacts anything that relies on CSS side effects, not just Vanilla Extract.
It's looking to me like this is an issue with esbuild's tree shaking: https://github.com/evanw/esbuild/issues/1370
In your example I was able to work around the issue by avoiding export *
in app/components/index.tsx
and explicitly re-exporting the component instead:
-export * from "./Test";
+export { Test } from "./Test";
By the way, I think manually re-exporting everything like this is a better pattern anyway. I've been burned in the past with files like this that make heavy use of export *
where you start to lose visibility over its API surface area, can't tell whether there are any name clashes, inadvertently make internals public API, etc. Obviously I'd prefer the esbuild bug was fixed, but I'd still recommend making this change even if the bug wasn't there.
Thanks for looking into this! Seems like a fair work around until the issue is fixed in esbuild.
Seems like the issue is fixed in esbuild version 17.7: https://github.com/evanw/esbuild/issues/1370 https://github.com/evanw/esbuild/releases/tag/v0.17.7
Version 0.17.7 introduced other tree shaking issues: https://github.com/evanw/esbuild/issues/2933
I'm closing this for now since it's an esbuild issue that can't be fixed in Remix. We've made a note of this issue in the CSS bundling setup guide to help Remix consumers avoid this.
@markdalgleish I have this specific issue with named exports but only in production mode (NODE_ENV=production
) and when the component is re-exported to root.tsx
. Here are a few interesting facts I noticed:
- In dev mode, the CSS files are injected into the header but not in prod.
- The re-exported styles are missing in the build folder after running
remix vite:build
. - If I import the component with React's
lazy(..)
function, the styles are created into the build folder and injected into the header in both dev and prod, solving the problem 🤔
Is this problem still related to the esbuild tree shacking issue? Maybe it's more related to SSR and how the root.tsx
component works?
Version Info:
- Remix: v2.9.2 (with Vite)
- vite: v5.3.1
- @vanilla-extract/css: v1.15.3
- @vanilla-extract/vite-plugin: v4.0.11
UPDATE: I found out that this is not an issue! The re-exported styles are just part of the root route chunk. The problem was that we were using Ant Design, which was loaded last, causing an override over the custom Vanilla Extract styles. However, I'm still not sure why it works differently on dev 🤔
I was able to solve it by forcing Antd styles to load before <Links />
:
<html lang="en">
<head>
<Meta />
<link rel="stylesheet" href="/antd.css" />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
</body>
</html>