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 =>
instead of my Home.svelte
It works if I do import Home from './home/Home.svelte'
I can't figure out why.
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.
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:
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
}
};
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With