Support Vanilla JS CSS Modules / CSS import attributes
m-jung opened this issue · 3 comments
Description
It seems that Vite does not support imports of CSS Style Sheets in ES modules with or without import attributes like import styles from './styles.css'
or import styles from './styles.css' with { type: 'css' }
.
A workaround seems to be the ?inline
query parameter like import styles from './styles.css?inline'
.
I see that import attributes are at state 3 still, but constructable stylesheets aren't and ES-Modules are both in base-line now.
So i'd like the (configurable) support to import CSS as CSSStyleSheet
.
Suggested solution
A configurable option to handle imports of *.css as CSS Modules / CSSStyleSheet
.
Alternative
No response
Additional context
Why don't you just use the ?inline
-query?
We're targeting browsers with native CSS Module import support, like Chrome, for internal enterprise web apps.
Third parties now want to start using our custom elements which make use of those imports.
Since they do not have access to the source and we cannot add ?inline
to all imports, the potential users are limited to use the bundled version, which hinders them to extend und bundle custom-element on their behalf.
See the reproducer on stackblitz which illustrates the issue, when running npm run build
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Start a new pull request in StackBlitz Codeflow.
It appears that Vite deliberately strips the import attribute syntax:
vite/packages/vite/src/node/plugins/importAnalysis.ts
Lines 494 to 497 in 3af02bd
Worth noting that import attributes are supported by TypeScript along with native support in Chrome.
It would be great it vite
could avoid adulterating the import syntax in my code so that the runtime itself can interpret what I authored.
The workaround right now:
// vite strips the type declaration syntax
import stylesheet from './demo-badge.css' with { type: 'css' };
// vite does not modify the syntax
const { default: stylesheet } = await import('./demo-badge.css', { with: { type: 'css' } });
Some prior comments on the topic:
As a first step toward solving this issue, I think it might be nice to have an option to disable the current CSS runtime behavior entirely.
In other words, *.css
files would be treated the same as any non-JS file type (e.g. *.mdx
, .tsx
, etc.), and plugins would be able to transform the CSS files to JS as needed.
This would fit the usecase of the LWC framework – in LWC, importing a CSS file returns a function:
import stylesheet from './styles.css' // imports a function that returns a string
Currently, this functionality doesn't work in Vite even with our Rollup plugin (@lwc/rollup-plugin
), due to Vite's default handling of CSS. (I have a minimal repro of this issue using Vitest.)
Unfortunately, the ?inline
or with { type: 'css' }
solutions would not work for us, because it would be a breaking change for existing components (which do not use such syntax when importing stylesheets).
Potentially, our Rollup plugin could apply these transformations itself (to the .js
files that are importing .css
files), but I wonder if a more generic "disable the current CSS behavior" option would be a simpler solution for other web component frameworks in general.