简体   繁体   中英

How to import enum using path alias in Svelte Kit?

The Problem

I cannot import an enum from a .ts file into a __layout.svelte component using a path alias.

I have an interface that I can export and use without problem through the path alias. Importing an enum throws an error: Cannot find module...

However, importing the enum using a relative path ( ../types/types-load-menu-paths ) works fine.

Why am I encountering issues using path aliases?

I also encounter a similar problem with aliasing when trying to import from the src directory. Eg, I have an app.css file I cannot reference.

Setup

  • I have a file named types-load-menu-path.ts with an enum (MenuOrder) and an interface (Paths)
  • I import them into a __layout.svelte component using a path alias: $types
  • The interface is imported using import type { Paths } from '$types/types-load-menu-paths';
  • The enum is imported using import { MenuOrder } from '$types/types-load-menu-paths'; otherwise I get an error: 'MenuOrder' cannot be used as a value because it was imported using 'import type'

tsconfig.json

{
    "extends": "./.svelte-kit/tsconfig.json",
    "compilerOptions": {
        "moduleResolution": "node",
        "module": "es2020",
        "lib": ["es2020", "DOM"],
        "target": "esnext",
        "strict": true,
        /**
            svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
            to enforce using \`import type\` instead of \`import\` for Types.
            */
        "importsNotUsedAsValues": "error",
        "isolatedModules": true,
        "resolveJsonModule": true,
        "sourceMap": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "baseUrl": ".",
        "allowJs": true,
        "checkJs": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "paths": {
            "$lib": ["src/lib"],
            "$lib/*": ["src/lib/*"],
            "$src/*": ["src/*"],
            "$components/*": ["src/lib/components/*"],
            "$stores/*": ["src/lib/stores/*"],
            "$templates/*": ["src/lib/templates/*"],
            "$utils/*": ["src/lib/utils/*"],
            "$types/*": ["src/types/*"],
            "$styles/*": ["src/styles/*"]
        }
    },
    "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte", "src/**/*.css"]
}

svelte.config.js

import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
import path from 'path'; 

/** @type {import('@sveltejs/kit').Config} */
const config = {
    // Consult https://github.com/sveltejs/svelte-preprocess
    // for more information about preprocessors
    preprocess: [
        preprocess({
            postcss: true
        })
    ],

    kit: {
        adapter: adapter()
    },

    vite: { 
        resolve: { 
            alias: { 
                "$src": path.resolve('./src/*'),
                "$lib": path.resolve('./src/lib/*'),
                "$components": path.resolve('./src/lib/components/*'),
                "$stores": path.resolve('./src/lib/stores/*'),
                "$templates": path.resolve('./src/lib/templates/*'),
                "$utils": path.resolve('./src/lib/utils/*'),
                "$types": path.resolve('./src/types/*'),
                "$styles": path.resolve('./src/styles'),
            }
        }
    }
};

export default config;

types-load-menu-paths.ts

export enum MenuOrder {
    HOME,
    ABOUT,
    BLOG,
}

export interface Paths {
    path: string;
    title: string;
    order: MenuOrder;
}

__layout.svelte

<script context="module" lang="ts">

    ...

    import type { Paths } from '$types/types-load-menu-paths';
    import { MenuOrder } from '../types/types-load-menu-paths';
    
    ...

</script>

A Solution

Inside the svelte.config.js :

  • Move vite.resolve.alias... inside kit :
  • Remove trailing * in resolve ; eg $components: resolve('./src/lib/components/*') should be $components: resolve('./src/lib/components/')

If the * is not removed, an SSR error is thrown:

Error: failed to load module for ssr: /src/lib/components/*/DefaultLayout/Header.svelte

svelte.config.js

import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
import { resolve } from 'path';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    // Consult https://github.com/sveltejs/svelte-preprocess
    // for more information about preprocessors
    preprocess: [
        preprocess({
            postcss: true
        })
    ],

    kit: {
        adapter: adapter(),
        // moved vite.resolve.alias... inside kit and removed path ../* 
        vite: {
            resolve: {
                alias: {
                    $src: resolve('./src/'),
                    $lib: resolve('./src/lib/'),
                    $components: resolve('./src/lib/components/'),
                    $stores: resolve('./src/lib/stores/'),
                    $templates: resolve('./src/lib/templates/'),
                    $utils: resolve('./src/lib/utils/'),
                    $types: resolve('./src/types/'),
                    $styles: resolve('./src/styles')
                }
            }
        }
    },
};

export default config;

More information can be found in the SvelteKIT FAQ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM