Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setup tsconfig path in svelte

Using Svelte and typescript, I would like to use paths for component import.

I have the following tsconfig.json

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "include": ["src/**/*"],
  "main": "src/main.ts",
  "exclude": ["node_modules/*", "__sapper__/*", "public/*"],
  "compilerOptions": {
    "baseUrl": "./",
    "module": "es2020",
    "target": "es2020",
    "paths": {
      "@src/*": ["src/*"],
      "@environments/*": ["src/environments/*"]
    }
  }
}

Now when I do

<script lang="ts">
  import Home from '@src/home/Home.svelte'
</script>

<style>
  main {
    width: 100%;
    height: 100%;
    position: relative;
  }
</style>

<main>
  <Home/>
</main>

The home point to some svelte internal file =>

enter image description here

instead of my Home.svelte

enter image description here

It works if I do import Home from './home/Home.svelte' I can't figure out why.

like image 263
Bobby Avatar asked Aug 15 '20 15:08

Bobby


2 Answers

The svelte template use rollupjs as the bundler. It is used to recursively parse all your files and transpile (compile for Svelte) into a single .js file that every browser can understand.

So when you want to use aliases in your import you need to tell to the bundler how it as to handle it. You need for that in the rollup.config.js file to declare all the aliases like you do in the tsconfig.json.

To declare them you will need to install an external package called @rollup/plugin-alias and use it like that in the rollup.config.js:

import alias from '@rollup/plugin-alias';
import path from 'path'

const projectRootDir = path.resolve(__dirname);


export default {
    ...
    plugins: [
        ...
        alias({
            entries: [
                { 
                    find: '@src',
                    replacement: path.resolve(projectRootDir, 'src')
                }
            ]
        }),
        ...
    ],
};

Now rollupjs is able to resolve all the paths that contain the @src alias.

Check this repo for a working example.

like image 189
johannchopin Avatar answered Nov 13 '22 09:11

johannchopin


I spend a lot of time to solve this issue. A lot of time...

The only way I finally made it work is a combination of these steps:

  1. Setup paths in tsconfig like you did.
  2. Install @ropllup-plugin-alias like this (the important part is plugins section -> alias:
import resolve from '@rollup/plugin-node-resolve';
import alias from "@rollup/plugin-alias";
import svelte from 'rollup-plugin-svelte';

import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';

import path from "path";

const projectRootDir = path.resolve(__dirname);

const production = !process.env.ROLLUP_WATCH;


export default {
    input: 'src/main.ts',
    output: {
        sourcemap: true,
        format: 'iife',
        name: 'app',
        file: 'public/build/bundle.js'
    },
    plugins: [
    svelte({
            // enable run-time checks when not in production
      dev: !production,
      extensions: [ ".svelte" ],
            // we'll extract any component CSS out into
            // a separate file - better for performance
            css: css => {
                css.write('public/build/bundle.css');
            },
            preprocess: sveltePreprocess(),
    }),

    alias({
      entries: [
        { find: "@src", replacement: path.resolve(projectRootDir, 'src') },
        { find: "@layout", replacement: path.resolve(projectRootDir, 'src/layout') },
        { find: "@public", replacement: path.resolve(projectRootDir, 'public') },
        { find: "@app", replacement: path.resolve(projectRootDir, 'src/app') },
        { find: "@components", replacement: path.resolve(projectRootDir, 'src/components') },
        { find: "@util", replacement: path.resolve(projectRootDir, 'src/util') },
        { find: "@stores", replacement: path.resolve(projectRootDir, 'src/stores') }
      ]
    }),

        resolve({
            browser: true,
            dedupe: ['svelte']
    }),
    
    commonjs(),

    typescript({ sourceMap: !production }), 

        
        !production && serve(),

        
        !production && livereload('public'),

        
        production && terser()
    ],
    watch: {
        clearScreen: false
    }
};

  1. And the last one is... well, it works for me only with specifying the extension.

This one works: import something from "@app/module.ts";

This one do not: import something from "@app/module";

I hope it helps in your case too.

like image 2
Eric Rovell Avatar answered Nov 13 '22 08:11

Eric Rovell