You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When building a Vite library with preserveModules: true and CSS imported via the standard with { type: 'css' } import attribute (processed by vite-plugin-standard-css-modules), the output contains files with ? in their name — e.g. gui-element.styles.scss?inline.js.
Downstream bundlers like webpack and Next.js treat ? as a query string separator when resolving module paths, so they look for ./styles/gui-element.styles.scss (the part before ?) instead of the actual file, causing a build failure.
Error
Module not found: Can't resolve './styles/gui-element.styles.scss'
> 1 | import e from "./styles/gui-element.styles.scss?inline.js";
Root cause
vite-plugin-standard-css-modules transforms import x from './foo.scss' with { type: 'css' } into:
Vite's built-in ?inline CSS mechanism then resolves this to a virtual module with ID path/to/foo.scss?inline. With preserveModules: true, Rolldown uses the module ID directly as the output filename, producing foo.scss?inline.js.
Rolldown's sanitizeFileName option does not apply to preserveModules entry chunks (tracked in rolldown/rolldown#8761), so there is no built-in way to strip the ? before it reaches the filesystem.
Description
When building a Vite library with
preserveModules: trueand CSS imported via the standardwith { type: 'css' }import attribute (processed byvite-plugin-standard-css-modules), the output contains files with?in their name — e.g.gui-element.styles.scss?inline.js.Downstream bundlers like webpack and Next.js treat
?as a query string separator when resolving module paths, so they look for./styles/gui-element.styles.scss(the part before?) instead of the actual file, causing a build failure.Error
Root cause
vite-plugin-standard-css-modulestransformsimport x from './foo.scss' with { type: 'css' }into:Vite's built-in
?inlineCSS mechanism then resolves this to a virtual module with IDpath/to/foo.scss?inline. WithpreserveModules: true, Rolldown uses the module ID directly as the output filename, producingfoo.scss?inline.js.Rolldown's
sanitizeFileNameoption does not apply topreserveModulesentry chunks (tracked in rolldown/rolldown#8761), so there is no built-in way to strip the?before it reaches the filesystem.Environment
Reproduction
Output:
Workaround
Use
entryFileNames(which covers all modules underpreserveModules) to sanitize the filename:This produces
my-element.styles.scss_inline.jsand updates all import references accordingly.Expected behavior
Either:
sanitizeFileNameshould be applied topreserveModulesentry chunks (fixing the root cause in [Bug]: sanitizeFileName is ignored for JS chunks when preserveModules: true with object-form entry rolldown/rolldown#8761), orpreserveModules+ CSS?inlineand recommend theentryFileNamesworkaround.