language-tools: Cannot find module '$lib/...' or '$app/...' from language server for .svelte files in default configuration of sveltekit

Describe the bug

In a fresh install of sveltekit with demo app and typescript, LSP works fine out of the box except for imports from the $ aliases in .svelte files.

These throw a diagnostic such as Cannot find module '$lib/Counter.svelte' or its corresponding type declarations and jump to definition does not work for those imported symbols.

These diagnostics disappear if I replace $lib or $app with absolute paths and jump to definition starts working.

These diagnostics DO NOT happen in .ts files, where jump to definition works fine for symbols imported from $app, for example (see src/lib/form.ts in the demo app).

Reproduction

I’m using a fresh install of Node 16.14.2 LTS straight from the node main page tarball. Fresh global installs of svelte-language-server, typescript-language-server and typescript. Using the Helix editor which has a native LSP client, using the default config that automatically finds svelteserver for .svelte files and typescript-language-server for .js and .ts files.

I set up a new sveltekit project as per instructions on sveltekit main page answering yes for typescript and demo app and no for everything else. Cd to app dir, npm install, npm run dev -- --open. No changes made to anything.

Edit a .svelte file from the app root dir: hx src/routes/index.svelte

As soon as the language server loads, LSP features start working fine but it throws a diagnostic for the line import Counter from '$lib/Counter.svelte'; that reads: Cannot find module '$lib/Counter.svelte' or its corresponding type declarations and jump to definition does not work for that symbol (works fine otherwise for everything else in the same file).

The about.svelte page does the same thing for import { browser, dev } from '$app/env'; .

Expected behaviour

No diagnostic, jump to definition works.

System Info

  • OS: Debian 11
  • IDE: Helix

Which package is the issue about?

language-server

Additional Information, eg. Screenshots

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 7
  • Comments: 31 (3 by maintainers)

Most upvoted comments

I encountered this issue early on in an empty svelte-kit app. npm run prepare just told me that I had a missing script. Instead, I just needed to manually add the following to .svelte-kit/tsconfig.json:

"paths": {
  "$lib": [
      "src/lib"
  ],
  "$lib/*": [
      "src/lib/*"
  ]
},

Had missing $lib in tsconfig.json. Svelte added everything by itself after I ran npm run check.

I got to the same answer as @dustincleveland, although worth clarifying that "paths" needs to be under compilerOptions. E.g.,

{
  "compilerOptions": {
    ...,
    "paths": {
      "$lib/*": ["src/lib/*"],
      ...
    },
}

In your case it was probably just a lag of VSCode However it can also happen if you didn’t have any $lib references initially (say you chose barebones instead of demo app at setup). What you would need to do in that case is simply run npm run prepare (yarn prepare, etc.) so the framework generates aliases automatically. You can see it in file .svelte-kit/tsconfig.json

Restarting VSCode worked, nevermind.

I ran into the same problem using Helix-editor turns out it is because svelte language server could not find the root? of the project. Two ways to fix it:

git init at root of the project, seems .git is used to find the root.

The other way: Set the svelte language roots property to include “package.json” in ~/.helix/config/languages.toml, and the problem went away.

[[language]] name = "svelte" roots = ["package.json"]

Don’t know if helix needs a PR or not.

in svelte.config.js

kit: { alias: { ‘lib/': './src/routes/lib/’ } }

Problem still happening nowadays. I just did a npm create svelte@latest myapp choosing a skeleton project with typescript and the $lib folder couldn’t be found. I got it working by modifying the following files: svelte.config.js

import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite';

const config = {
	preprocess: vitePreprocess(),
	kit: {
		adapter: adapter(),
            files: {
                lib: './src/routes/lib/'
            }
	}
};
export default config;

And tsconfig.json:

{
    "extends": "./.svelte-kit/tsconfig.json",
    "compilerOptions": {
         <default options here>
        "paths": {
            "$lib": [
                "./src/routes/lib"
            ],
            "$lib/*": [
                "./src/routes/lib/*"
            ]
        }
    }
}

Unfortunately, I’m having the same issue 😿 but all my boxes are checked. tsconfig contains the path aliases (auto-generated so no chance of human error). Got the Svelte extension freshly installed. Have restarted VSCode like 10 times 😦. image

The ambient $app module wasn’t detecting for me when setting up SvelteKit in a pre-existing Tauri project.

Deleting the include setting in my root tsconfig.json fixed the problem.

Inheriting from .svelte-kit/tsconfig.json as much as possible seems to be what is needed for SvelteKit to work as expected.

If you still want to customize your tsconfig.json:

  • ./$types needs .svelte-kit/types/**/$types.d.ts to be in the include array
  • $app needs vite.config.ts to be in the include array
  • $env needs .svelte-kit/ambient.d.ts to be in the include array
  • $lib needs to be properly configured in your compilerOptions.paths setting

tsconfig.json and remove "baseUrl": "./src",

How i fix TypeScript error Cannot find module '$lib/server/my-functions' or its corresponding type declarations.ts(2307)

// src/routes/my-page/+page.server.ts
import { get_order } from '$lib/server/my-functions'
                          ^ Cannot find module '$lib/server/my-functions' or its corresponding type declarations.ts(2307)

My SvelteKit version was:

		"@sveltejs/kit": "^2.5.0",

How i solved the problem:

1. Change the moduleResolution:

./tsconfig.json

-		"moduleResolution": "nodenext",
+		"moduleResolution": "bundler",

This is by default from SvelteKit v2.0.0: https://kit.svelte.dev/docs/migrating-to-sveltekit-2#updated-dependency-requirements

2. In my case i still needed to add aliases directly to tsconfig.json (trying to set alias in svelte.config.js didn’t work)

./tsconfig.json

{
	"extends": "./.svelte-kit/tsconfig.json",
	"compilerOptions": {
		"paths": {
+			"$lib": ["./src/lib"],
+			"$lib/*": ["./src/lib/*"],
+			"$utils": ["./src/lib/utils"],
+			"$utils/*": ["./src/lib/utils/*"],
+			"$components": ["./src/lib/components"],
+			"$components/*": ["./src/lib/components/*"],
		},

pnpm run dev and VS Code F12 «Go to Definition» now works correctly! 👍

same here, trying to figure out how to reintroduce $lib alias into a skeleton project

I tried editing my tsconfig.json, but every time I run npm run dev it changes it back to "paths":{}. How do I prevent this?

hehe - just discovered that the root tsconfig.json which extends the .svelte-kit/tsconfig.json was completely missing. 🤦‍♂️

Wild guess, did you modify the tsconfig? The paths config would override the extended config. svelte kit would warn you if that happens.

prepare script has been removed from the template

https://github.com/sveltejs/kit/blob/master/packages/create-svelte/CHANGELOG.md#200-next152

It would also be generated when you started the dev server. If you have use cases where you don’t want to spin up the dev servers, you can add the script back just don’t name it as prepare. it was removed for a reason.