language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

When using SvelteKit in a VSCode workspace, scss import statements like `@use` inside of style tags in components show IDE errors using virtually any path, but compile in the dev server

Open FaintentDev opened this issue 6 months ago • 4 comments

Describe the bug

im going to reopen this issue created before that got closed however i demand it fixed where IDE-only errors would appear when using a workspace with Svelte apps and not only does it occur when importing using prependData but also @use/@import statements from any

Reproduction

check the link for the previous user's reproduction

Expected behaviour

check the link for the previous user's expected behavior

System Info

  • OS: Windows
  • IDE: VSCode

Which package is the issue about?

Svelte for VS Code extension

Additional Information, eg. Screenshots

the only workaround i could finally come up (which took 8 hours) was with is this added to svelte.config.js (from a child of my pnpm workspace):

import { sveltePreprocess } from 'svelte-preprocess'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

const dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url))

// Resolve the absolute path, then remove Windows drive letter and normalize slashes
const scssPath = path
	.resolve(dirname, '../../packages/ui/src/lib/styles/prepend.scss') // replace with your relative import path
	.replace(/^([A-Za-z]:)/, '')
	.replace(/\\/g, '/')

const config = {
	kit: {
		adapter: adapter(),
		alias: { ui: '../../packages/ui/src/lib' },
	},
	preprocess: [
		sveltePreprocess({
			scss: {
				prependData: `@use '${scssPath}' as *;`,
			},
		}),
	],
}

this finally fixes the IDE-only scss import errors in

however this is definitely a bug with the extension and i propose a fix to this as quoted by ChatGPT:

The Svelte Language Server, which powers the VSCode extension for Svelte, resolves paths relative to the current working directory. In a monorepo setup, when you open the workspace root in VSCode, the language server may not correctly resolve SCSS imports like @use '$lib/styles', leading to false-positive errors in the editor. This problem does not affect the actual build process, which is why your project compiles without issues.

FaintentDev avatar Apr 30 '25 02:04 FaintentDev

The workaround is the correct way to deal with this problem, as mentioned in the docs https://github.com/sveltejs/language-tools/blob/master/docs/preprocessors/scss-less.md. You can find this documentation following the link in the first few lines of the README. As for the solution for vitepreprocess, you can follow https://github.com/sveltejs/language-tools/issues/2323#issuecomment-2019730792.

As explained in both linked issues and the Chatgpt answer you quoted, this is because of the different working directory, which affects relative path resolving. Maybe we could try to spawn a child process with a different working directory in the future, but that would increase the memory consumption and might also have a performance impact because of the inter-process communication cost.

jasonlyu123 avatar Apr 30 '25 02:04 jasonlyu123

alright i understand, though its never really specified in those answers about a workspace/monorepo kind of situation and false-positives from the IDE, all of those answer assume theres also issues on the dev server, plus they only specify errors from preprocessorOptions and not including project-wide scss imports which also had false positives for me

i only suggest making the documentation a bit more clearer about that because i was searching for hours back to back including chatgpt for any solution regarding my issue, and i understand the costs of fixing that now thanks for explaining dude

the vitePreprocess implementation works, i just had to also add it to vite.config.js and change prependData to additionalData:

svelte.config.js

const config = {
	preprocess: [
		vitePreprocess({
			style: {
				css: {
					preprocessorOptions: {
						scss: {
							additionalData: `@use '${scssPath}' as *;`,
						},
					},
				},
			},
		}),
	],

vite.config.js

export default defineConfig({
	css: {
		preprocessorOptions: {
			scss: {
				additionalData: `@use '${scssPath}' as *;`,
			},
		},
	},

FaintentDev avatar Apr 30 '25 14:04 FaintentDev

Can't figure out how to workaround this with sveltekit's $lib and @use.

None of these fix the issue:

/** @type {import('@sveltejs/kit').Config} */
const config = {
  // Consult https://svelte.dev/docs/kit/integrations
  // for more information about preprocessors
  preprocess: vitePreprocess({
    style: {
      css: {
        preprocessorOptions: {
          scss: {
            api: "modern-compiler",
            loadPaths: [
              resolve(import.meta.dirname, "..", "src/lib"),
              resolve(import.meta.dirname, ".."),
              resolve(import.meta.dirname),
              "packages/web",
              "packages/web/src",
              "packages/web/src/lib",
              "./packages/web",
              "./packages/web/src",
              "./packages/web/src/lib",
            ],
          }
        }
      }
    }
  }),

This also doesn't work:

  kit: {
    files: {
      lib: resolve(import.meta.dirname, "src/lib"),
    },
  },

Adding process.chdir(import.meta.dirname); to the end of svelte.config.js works but only for one package in a workspace


Edit: following worked

    preprocess: vitePreprocess({
        style: {
            resolve: {
                alias: {
                    // https://github.com/sveltejs/language-tools/issues/1986#issuecomment-2317238374
                    $lib: join(import.meta.dirname, 'src/lib'),
                },
            },
        },
    }),

ty @jasonlyu123

MingweiSamuel avatar May 04 '25 22:05 MingweiSamuel

@MingweiSamuel https://github.com/sveltejs/language-tools/issues/1986#issuecomment-2317238374

jasonlyu123 avatar May 08 '25 04:05 jasonlyu123

Thank you, this solution works for me:

preprocess: vitePreprocess({
        style: {
            resolve: {
                alias: {
                    // https://github.com/sveltejs/language-tools/issues/1986#issuecomment-2317238374
                    $lib: join(import.meta.dirname, 'src/lib'),
                },
            },
        },
    }),

Why this isn’t set as the default configuration? It appears to work correctly when I open a monorepo or simply a directory with SvelteKit. Setting this as the default could save users considerable time on configuration.

LexRiver avatar Jul 19 '25 09:07 LexRiver