remix icon indicating copy to clipboard operation
remix copied to clipboard

CSS bundle contents are tree-shaken when re-exporting a component/module

Open augustskare opened this issue 2 years ago • 3 comments

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.

Reproducible example

Expected Behavior

Styles should be included in the css bundle.

Actual Behavior

Styles are ignored, and not included in the css bundle.

augustskare avatar Jan 26 '23 08:01 augustskare

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

markdalgleish avatar Jan 26 '23 21:01 markdalgleish

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.

markdalgleish avatar Jan 26 '23 22:01 markdalgleish

Thanks for looking into this! Seems like a fair work around until the issue is fixed in esbuild.

augustskare avatar Jan 27 '23 06:01 augustskare

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

ledenis avatar Apr 01 '23 15:04 ledenis

Version 0.17.7 introduced other tree shaking issues: https://github.com/evanw/esbuild/issues/2933

markdalgleish avatar Apr 02 '23 22:04 markdalgleish

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 avatar May 09 '23 00:05 markdalgleish

@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

JoseLion avatar Jun 21 '24 16:06 JoseLion

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>

JoseLion avatar Jun 21 '24 23:06 JoseLion