5

I'm trying to import enums, objects, functions, and svelte components by using absolute paths to files, but the compiler can't find them.

This is how i do the imports:

<script lang=ts>
    import { MyEnum } from "src/lib/enums";
    ... code ...
<script/>

The VS Code compiler does not complain about the path.

I get the following error message on the window when running the app:

[plugin:vite:import-analysis] Failed to resolve import "src/lib/enums" from "src\lib\GUI\ObjectOnBoard.svelte". Does the file exist?
35 |  
36 |  const { Object: Object_1 } = globals;
37 |  import { MyEnum } from "src/lib/enums";
   |                              ^

I have done some research, and i've found out that there might be some issues regarding my config files, but i don't know how to configure these files in order to make the referencing work. These are the config files (the ones i think are relevant?) in my project:

vite.config.ts:

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [svelte()],
})

svelte.config.js:

import sveltePreprocess from 'svelte-preprocess'

export default {
  // Consult https://github.com/sveltejs/svelte-preprocess
  // for more information about preprocessors
  preprocess: sveltePreprocess(),
}

tsconfig.json:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "resolveJsonModule": true,
    "baseUrl": ".",
    /**
     * Typecheck JS in `.svelte` and `.js` files by default.
     * Disable checkJs if you'd like to use dynamic types in JS.
     * Note that setting allowJs false does not prevent the use
     * of JS in `.svelte` files.
     */
    "allowJs": true,
    "checkJs": true,
    "isolatedModules": true,
  },
  "include": ["src/**/*.d.ts", "src/**/*.{svelte,ts,js}"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

The answer given below works for compiling the code, so now it actually runs which is awesome! But there are still some problem regarding VS Code autocompletion and error messages (red wiggly lines).

Specifying absolute paths works flawless inside of .svelte files, but in .ts files, typescript keeps alerting the error, eventhough the code compiles and works:

"Cannot find module 'src/lib/objects/outlet' or its corresponding type declarations."

This error statements appears within the file "src/lib/MainDataStructure".

I've tried "Restart TS Server", but it does not help. I've looked at this question which has alot of suggestions on how to solve this, but none works for me.

This is my current tsconfig.json file:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "compilerOptions": {
    "moduleResolution": "node",
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "resolveJsonModule": true,
    "allowSyntheticDefaultImports": true,
    /**
     * Typecheck JS in `.svelte` and `.js` files by default.
     * Disable checkJs if you'd like to use dynamic types in JS.
     * Note that setting allowJs false does not prevent the use
     * of JS in `.svelte` files.
     */
    "allowJs": true,
    "checkJs": true,
    "isolatedModules": true,
    "baseUrl": ".",
    "paths": {
      "src/*": [
        "src/*"
      ],
    }
  },
  "include": ["src/**/*.d.ts", "src/**/*.{svelte,ts,js}"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

This is an image of my directory in the project:

enter image description here

Ólavur Nón
  • 161
  • 1
  • 13

1 Answers1

11

Under Node module resolution (set by tsconfig/svelte) those are not absolute file paths. They will be interpreted as relative to a Node module, in this case src.

If you want to refer to a local file, you might have to define a path alias first via the tsconfig.json:

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

(If your baseUrl is '.', then the src folder has to be at the same level as the configuration.)

When using Vite, you may also have to make its build system aware of the path mapping, there exists e.g. the package vite-tsconfig-paths which provides a plugin for that.

If you do not want the extra dependency or this does not work, you can specify the alias yourself in the vite.config.js:

// ...
import path from 'path';

export default defineConfig({
    // ...
    resolve: {
        alias: {
            src: path.resolve('src/'),
        },
    }
});

The Vite config step is important for the build to work, the tsconfig may be necessary to make editor tooling work (e.g. code completion and navigation in VS Code).


Note: SvelteKit has its own configuration for adding additional aliases.

H.B.
  • 166,899
  • 29
  • 327
  • 400
  • I tried adding "paths": { "src/*" : [ "src/*" ] } into compilerOptions, but it does not yet work. I don't think i can follow you on Node module resolution and baseUrl, could you elaborate? – Ólavur Nón Sep 17 '22 at 12:59
  • If you look at the `vite.config.js`, it has an import from `'vite'`. There is no such folder => By default imports look for modules in `node_modules` (unless they start with a `.`). This lookup mechanism is called "module resolution", and searching for `node_modules` is the mechanism for Node. – H.B. Sep 17 '22 at 13:07
  • The `baseUrl` option specifies what folder the paths used with the `path` option and other imports are relative to. – H.B. Sep 17 '22 at 13:08
  • (The TS config from `@tsconfig/svelte` sets `"moduleResolution": "node"`, by the way.) – H.B. Sep 17 '22 at 13:12
  • I don't really know what i want to set my configurations to, all i know is i want to specify the locations of files as like "src/lib/enums", and your answer does not seem to work for me unfortunately. Appart from adding "paths": { "src/*" : [ "src/*" ] } to compilerOptions, is there anything else i'm missing? – Ólavur Nón Sep 17 '22 at 13:24
  • I just noticed that Vite needs additional setup to handle this; edited my answer. – H.B. Sep 17 '22 at 13:26
  • Added some more info for a manual Vite fix. – H.B. Sep 17 '22 at 13:31
  • 1
    Amazing, adding the vite-tsconfig-paths package worked! – Ólavur Nón Sep 17 '22 at 13:54
  • Now i find, as you mentioned, that code completion regarding absolute path in typescript does not work, VS Code is giving an error on the absolute path, eventhough the code compiles and works (only in .ts files, .svelte files works fine). You mention the tsconfig file, what should i correct to make autocompletion work and get rid of the VS Code error? – Ólavur Nón Sep 18 '22 at 12:20
  • Depends on your folder structure, also make sure to restart the TS language server after changes to the config. Would recommend checking other questions like [this one](https://stackoverflow.com/questions/50679031/tsconfig-paths-not-working). – H.B. Sep 18 '22 at 12:50
  • I've tried almost every combination on the question you sent in the comment, but nothing works. I'm updating my question with further information... – Ólavur Nón Sep 18 '22 at 17:23
  • Sorry, I do not know what the issue with that might be. I would suggest moving that to a separate question since this is mainly a dev tooling issue, unrelated to Svelte. – H.B. Sep 18 '22 at 17:54