Skip to content
Advertisement

Import alias svelte component in typescript svelte

I want to import a svelte component in a typescript svelte component, it works for typescript file and other type of files, but in this case of svelte component, it resulted in a path error, here’s my code :

<script lang="ts">
    import LoadingIcon from "src/components/LoadingIcon.svelte";
</script>

It only works if i use ../../components/LoadingIcon.svelte instead of src/components/LoadingIcon.svelte

Here’s the error: Uncaught (in promise) TypeError: Failed to resolve module specifier "src/forms/groups/GroupFilterForm.svelte". Relative references must start with either "/", "./", or "../".

error

Here’s my tsconfig.json:

{
    "include": ["src/**/*"],
    "exclude": ["node_modules/*", "public/*", "tests/*", "docs/*", "demo/*"],
    "compilerOptions": {
        "rootDir": "src",
        "lib": ["es2017", "dom"],
        "target": "es2017",
        "baseUrl": ".",
        "noEmitOnError": true,
        "noErrorTruncation": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "allowSyntheticDefaultImports": true,
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "types": ["svelte", "node"],
        "typeRoots": ["./node_modules", "./src/types"]
    }
}

and here’s my rollup.config.js:

import svelte from "rollup-plugin-svelte";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import replace from "@rollup/plugin-replace";
import json from "@rollup/plugin-json";
import livereload from "rollup-plugin-livereload";
import { terser } from "rollup-plugin-terser";
import sveltePreprocess from "svelte-preprocess";
import copy from "rollup-plugin-copy";
import del from "rollup-plugin-delete";
const buildDir = "public/build";
const deploymentDir = "public";

const production = !process.env.ROLLUP_WATCH;

const dotenv = require("dotenv-flow");

dotenv.config({
    node_env: process.env.NODE_ENV,
    default_node_env: "development",
});

const fileDev = dotenv.listDotenvFiles("/", {
    node_env: "development",
});
const fileProd = dotenv.listDotenvFiles("/", {
    node_env: "production",
});

function serve() {
    let server;

    function toExit() {
        if (server) server.kill(0);
    }

    return {
        writeBundle() {
            if (server) return;
            server = require("child_process").spawn(
                "npm",
                ["run", "start", "--", "--dev"],
                {
                    stdio: ["ignore", "inherit", "inherit"],
                    shell: true,
                }
            );

            process.on("SIGTERM", toExit);
            process.on("exit", toExit);
        },
    };
}
const baseUrl =
    process.env.BASE_URL == "/"
        ? ""
        : "/" + (process.env.BASE_URL || "").replace(/^/|/$/g, "");
export default [
    {
        input: "src/main.ts",
        output: {
            sourcemap: true,
            format: "esm",
            name: "app",
            dir: `${buildDir}/`,
        },
        plugins: [
            del({ targets: `${deploymentDir}/*`, runOnce: true }),
            copy({
                targets: [
                    { src: "scripts/*", dest: `${buildDir}/` },
                    {
                        src: "src/index.html",
                        dest: `${deploymentDir}/`,
                        transform: (contents) => {
                            let content = contents.toString();
                            content = content.replace(
                                /(<%=)[s]{0,}(BASE_URL)[s]{0,}(%>)/gm,
                                baseUrl
                            );
                            return content;
                        },
                        copyOnce: true,
                    },
                    {
                        src: "src/assets/images/*",
                        dest: `${deploymentDir}/images/`,
                        copyOnce: true,
                    },
                    {
                        src: "src/assets/lang/*",
                        dest: `${deploymentDir}/lang/`,
                        copyOnce: true,
                    },
                    {
                        src: "src/assets/plugins/*",
                        dest: `${deploymentDir}/plugins/`,
                        copyOnce: true,
                    },
                ],
            }),
            json(),
            replace({
                "process.browser": true,
                "process.env.NODE_ENV": JSON.stringify(
                    production ? "production" : "development"
                ),
                "process.env.BASE_URL": JSON.stringify(process.env.BASE_URL),
                "process.env.API_URL": JSON.stringify(process.env.API_URL),
            }),
            svelte({
                dev: !production,
                css: (css) => {
                    css.write(`bundle.css`);
                },
                preprocess: sveltePreprocess({
                    postcss: {
                        configFilePath: "./postcss.config.js",
                    },
                    typescript: {
                        tsconfigFile: `./tsconfig.json`,
                    },
                }),
            }),
            resolve({
                browser: true,
                dedupe: ["svelte"],
                extensions: [".mjs", ".ts", ".js", ".json", ".node", ".svelte"],
            }),
            commonjs(),
            typescript({
                sourceMap: !production,
                inlineSources: !production,
            }),

            // In dev mode, call `npm run start` once
            // the bundle has been generated
            !production && serve(),

            // Watch the `public` directory and refresh the
            // browser on changes when not in production
            !production && livereload(deploymentDir),

            // If we're building for production (npm run build
            // instead of npm run dev), minify
            production && terser(),
        ],
        watch: {
            clearScreen: false,
        },
    },
];

Anyone knows how to fix this issue? thank you for your help

Advertisement

Answer

You are using baseUrl, which means some kind of path aliasing is introduced in the code. @rollup/plugin-typescript does not resolve these, so you need an extra step afterwards. You can use @rollup/plugin-alias for that.

Updated rollup.config.js:

// ... other imports
import alias from "@rollup/plugin-alias";

// ..
  plugins: [
    // ... after typescript({..})
    
    alias({
      entries: [
        // If you add a new top-level-folder besides src which you want to use, add it here
        { find: /^src(/|$)/, replacement: `${__dirname}/src/` },
      ],
    }),
5 People found this is helpful
Advertisement