lightningcss: relative @imports in imported preprocessor files resolve from the entry file directory
Describe the bug
With css.transformer: 'lightningcss', a plain CSS entry that imports a preprocessor file (.scss/.less/.sass) which itself contains relative @imports fails to compile, because the relative imports are resolved from the entry file's directory instead of the imported file's directory.
Errors with Error: Can't find stylesheet to import. pointing at the entry (src/main.css 1:9 root stylesheet) even though the imported file exists alongside box.scss.
The same project builds fine with the default css.transformer: 'postcss'.
Root cause: in compileLightningCSS's resolver.read(filePath) (packages/vite/src/node/plugins/css.ts), the preprocessor branch calls compileCSSPreprocessors(environment, id, ...) (and transformSugarSS(environment, id, ...)) passing the entry module id instead of the actually imported filePath. compileCSSPreprocessors sets opts.filename = cleanUrl(id), which the sass/less workers use as the base for relative import resolution (e.g. sassOptions.url = pathToFileURL(options.filename)). So @import './_vars.scss' inside an imported box.scss is resolved relative to the entry main.css's directory, not box.scss's directory.
For the typical preprocessor-entry case (.scss file imported as the module), id is that file's own path, so nothing is mis-rooted — the bug only surfaces when a plain CSS (or differently-located) file imports a preprocessor file from another directory.
I'm preparing a fix (pass filePath instead of id) and will open a PR.
Reproduction
https://gist.github.com/scs0209/ce8b8c144074f9851977636c447c07b4
/* src/main.css */
@import './components/box.scss';
/* src/components/box.scss */
@import './_vars.scss';
.box {
background: $bg;
}
/* src/components/_vars.scss */
$bg: cornflowerblue;
// vite.config.js
export default { css: { transformer: 'lightningcss' } }
Steps to reproduce
npm installthe gist project (vite 8.3.0 + lightningcss + sass)npm run build- Observe
Error: Can't find stylesheet to import.—./_vars.scssis resolved fromsrc/(entry dir) instead ofsrc/components/ - Switch
css.transformerto'postcss'→ the same build succeeds and inlines the variable correctly
System Info
System Info- Vite: 8.3.0 (and current
main) - lightningcss: latest (1.30+)
- sass: latest (1.8x)
- Node.js: v26.0.0
- npm: 11.12.1
- OS: macOS (arm64)
Source: vitejs/vite