Skip to content
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

CSS referenced assets are included even when the file is tree shaken #9073

Open
7 tasks done
Csszabi98 opened this issue Jul 13, 2022 · 3 comments
Open
7 tasks done

Comments

@Csszabi98
Copy link

Describe the bug

When a vite build includes a css file conditionally bound to environment variables the referenced assets by the CSS file always end up in the assets output folder even when the CSS file itself which references them does not.

index.css

@font-face {
    font-family: 'Roboto Regular';
    src: url('assets/roboto-regular.woff2') format('woff2');
    font-weight: normal;
    font-display: swap;
}

.env

VITE_INCLUDE_CSS="false"

index.js

if(import.meta.env.VITE_INCLUDE_CSS === 'true') {
  import('./index.css')
}

Expected behavior: index.css and roboto-regular.woff2 are not included in the build output folder.
Actual behavior: roboto-regular.woff2 is included in the build output folder.

Reproduction

https://github.com/Csszabi98/css-tree-shake-asset-issue

System Info

System:
    OS: macOS 12.4
    CPU: (10) x64 Apple M1 Pro
    Memory: 29.74 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 14.19.1 - ~/Library/Caches/fnm_multishells/957_1657095588762/bin/node
    npm: 6.14.16 - ~/Library/Caches/fnm_multishells/957_1657095588762/bin/npm
  Browsers:
    Brave Browser: 101.1.38.109
    Chrome: 103.0.5060.114
    Firefox: 101.0.1
    Safari: 15.5
  npmPackages:
    @vitejs/plugin-vue: ^2.3.3 => 2.3.3 
    vite: ^2.9.9 => 2.9.14

Used Package Manager

npm

Logs

No response

Validations

@bluwy
Copy link
Member

bluwy commented Jul 14, 2022

This seems to be because CSS in Vite are side-effectful by default, so Rollup would proceed to render the chunk even if it's unused. We can't change that though since it would break many other tooling, though Vite supports the ?inline query to disable side effects, and you have to inject it manually.

I also found another bug, which after using ?inline, the assets are still emitted, so that seems like a bug.

@bluwy
Copy link
Member

bluwy commented Nov 12, 2023

Update: I took another look at the issue today. The index.css (or main.css in the repro) is not included in the bundled CSS anymore, but the font assets are still emitted. It's because even though the import is unused, we would still transform it and it'll unconditionally emit the assets when transforming.

I'm not sure if there's a way for Rollup to skip transforming imports in dead code, I assume it doesn't treeshake after finished transforming/parsing a module. (Only during rendering?). So there isn't an easy fix on our side at the meantime, other that manually analyzing all assets emitted against the rendered chunks and delete them.

About the ?inline issue, I found that it's the same cause as above.

@patak-dev patak-dev removed the bug label Feb 10, 2024
@AriPerkkio
Copy link
Contributor

I'm running into same result but the import is coming from JS file and not CSS. @bluwy do you think this is a different issue and has different root cause?

https://stackblitz.com/edit/vite-unused-assets-tree-shake?file=main.js

Here the asset.png ends up in build even when main.js doesn't import the JS file that imports asset.png. Final build has no references to asset.png on JS or HTML side.

However when the process.env.NODE_ENV check is modified a bit, the dead code elimination seems to work better and asset.png is no longer included in build:

async function enableMocking() {
+  if (process.env.NODE_ENV === 'development') {
-  if (process.env.NODE_ENV !== 'development') {
-    return;
-  }

  const devTools = await import('./development-only');
  console.log(devTools);
+  }
}

The initial pattern is suggested by MSW documentation. I have MSW serving .png files in development mode, and these are now ending up in production build as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants