Gregory Pabian Full-stack software developer who loves building products.

Adding TypeScript to an existing Svelte project

4 min read 1391

Adding Typescript Svelte Project

Since 2020, Svelte has officially supported TypeScript, however, adding TypeScript to your Svelte project fundamentally changes your toolchain. Although we can’t predict your toolchain’s shape, we can assume it uses a web application bundler like webpack, Parcel, or Rollup. To add TypeScript to a Svelte project, we’ll essentially tell the bundler to transform TypeScript code into JavaScript code.

In this tutorial, we’ll learn how to configure TypeScript for Svelte using the three bundlers mentioned. To follow along with this article, you’ll need:

  • Basic knowledge of TypeScript
  • Understanding of your current toolchain
  • Yarn as your package manager

Let’s get started!

Shared build configuration

To follow along with the examples in this tutorial, first, we’ll configure our shared build. You should store your source files in the ./src/ directory and your build files in the ./build directory.

The entry point to the application will be the ./src/index.ts file, which will import the App class from the ./App.svelte file, initialize it, and default export it, as seen in the following example:

import App from './App.svelte';

export default (new App({ target: document.body }));

Svelte will inject the DOM entries into the body of an HTML page. Now, we can implement the App component:

<script lang="ts">
    import { onMount } from 'svelte';

    export let result: number = 2 + 2;

    onMount(() => {
        setTimeout(
            () => { result *= 3; },
            500,
        );
    });
</script>

<div>{ result }</div>

In the code block below, the <script lang="ts"> tag declaration and the variable definition export let result: number = 2 + 2; indicate that the code now exists in the TypeScript context.

Next, invoke the build script in npm by typing yarn build. The build script will run the bundler of your choice, compile your project, and produce a single ./build/bundle.js file. To use the ./build/bundle.js file, you should create a corresponding ./build/index.html file:

<!DOCTYPE html>
<html lang="en">
<body>
    <script defer src='./bundle.js'></script>
</body>
</html>

Now, navigate in your browser to the ./build/index.html file, and you should see your application in action! Now, let’s take a look at three popular bundlers you can use to migrate your application.

Rollup

Rollup is a library created by Rich Harris, the creator of Svelte. Therefore, it’s not surprising that Svelte supports Rollup through a custom integration package.

We made a custom demo for .
No really. Click here to check it out.

To use Rollup, we’ll first need to install the following packages as development dependencies:

  • @rollup/plugin-commonjs
  • @rollup/plugin-node-resolve
  • @rollup/plugin-typescript
  • @tsconfig/svelte
  • rollup
  • rollup-plugin-svelte
  • svelte
  • svelte-preprocess
  • tslib
  • typescript

To install these dependencies, we can use the partial ./package.json file below:

{
  "scripts": {
    "build": "rollup -c"
  },
  "devDependencies": {
    "@rollup/plugin-commonjs": "20.0.0",
    "@rollup/plugin-node-resolve": "13.0.4",
    "@rollup/plugin-typescript": "8.2.5",
    "@tsconfig/svelte": "2.0.1",
    "rollup": "2.56.2",
    "rollup-plugin-svelte": "7.1.0",
    "svelte": "3.42.1",
    "svelte-preprocess": "4.7.4",
    "tslib": "2.3.1",
    "typescript": "4.3.5"
  }
}

Alternately, we can install these dependencies using Yarn:

yarn add @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-typescript @tsconfig/svelte rollup rollup-plugin-svelte svelte svelte-preprocess tslib typescript -E -D

TypeScript configuration for Rollup

Next, we’ll configure TypeScript for Svelte and Rollup using the  ./tsconfig.json file below:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "include": ["src/**/*"],
  "exclude": ["node_modules/*"]
}

The @tsconfig/svelte project will import some additional configuration into our project. You can add other settings as desired, but first, ensure they do not conflict with Svelte.

Rollup configuration

Let’s add the necessary configuration for Rollup. In the code block below, you’ll see our exemplary ./rollup.config.js file, which sets up the correct preprocessing through the svelte-preprocess library:

import svelte from 'rollup-plugin-svelte';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';

export default {
    input: './src/index.ts',
    output: {
        format: 'iife',
        file: './build/bundle.js'
    },
    plugins: [
        svelte({
            preprocess: sveltePreprocess(),
        }),
        resolve({ browser: true }),
        commonjs(),
        typescript(),
    ],
};

Next, we’ll create a TypeScript triple-slash directive that informs the compiler about a dependency on the svelte package. We’ll need to create a file called ./src/global.d.ts and add the following content:

/// <reference types="svelte" />

With these steps completed, you should be able to compile your project using Rollup.

webpack

webpack is another popular bundler that has a customized integration package for Svelte. To migrate TypeScript to Svelte using webpack, we reduced the template-webpack to only the crucial pieces.

To get started, we’ll install the following packages as development dependencies:

  • @tsconfig/svelte
  • svelte
  • svelte-loader
  • svelte-preprocess
  • ts-loader
  • typescript
  • webpack
  • webpack-cli

We can install these dependencies using the following package.json:

{
    "scripts": {
        "build": "webpack"
    },
    "devDependencies": {
        "@tsconfig/svelte": "1.0.10",
        "svelte": "3.31.2",
        "svelte-loader": "3.0.0",
        "svelte-preprocess": "4.3.0",
        "ts-loader": "8.0.4",
        "typescript": "4.0.3",
        "webpack": "5.16.0",
        "webpack-cli": "4.4.0"
    }
}

If you prefer to use Yarn, you can run the code below:

yarn add @tsconfig/svelte svelte svelte-loader svelte-preprocess ts-loader typescript webpack webpack-cli -E -D

TypeScript configuration for webpack

Now, let’s define a basic TypeScript configuration using the partial ./tsconfig.json file provided below. As you can see, we’ll import some configuration from the @tsconfig/svelte project below:

{
    "extends": "@tsconfig/svelte/tsconfig.json",
    "include": ["src/**/*"],
    "exclude": ["node_modules/*"]
}

webpack configuration

To configure webpack for Svelte and TypeScript, we’ll have to make the following changes to our webpack configuration:

  • Define an entry point as a TypeScript file
  • Direct webpack to use ts-loader to process TypeScript files
  • Direct webpack to use svelte-loader and svelte-preprocess to process Svelte files

The configuration stored in the ./webpack.config.js file should look like the following code:

const path = require('path');
const sveltePreprocess = require('svelte-preprocess');

module.exports = {
    entry: {
        'bundle': ['./src/index.ts']
    },
    resolve: {
        alias: {
            svelte: path.dirname(require.resolve('svelte/package.json'))
        },
        extensions: ['.mjs', '.js', '.ts', '.svelte'],
        mainFields: ['svelte', 'browser', 'module', 'main']
    },
    output: {
        path: path.join(__dirname, '/build'),
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                loader: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.svelte$/,
                use: {
                    loader: 'svelte-loader',
                    options: {
                        preprocess: sveltePreprocess(),
                    }
                }
            }
        ]
    },
};

If you performed these steps correctly, you should be able to compile and run your project successfully using webpack.

Parcel

Finally, we’ll take a look at Parcel. Parcel is not currently supported by Svelte, however, it is a popular and versatile bundler that is used widely by developers.

At the time of writing, Parcel 2 is a release candidate. The information in the section below refers to Parcel 1.

When using Parcel, you need to ensure the following development dependencies are installed:

  • @tsconfig/svelte
  • parcel-bundler
  • parcel-plugin-svelte
  • svelte
  • svelte-preprocess
  • typescript

To perform the migration, you can use the following partial package.json file:

{
  "scripts": {
    "build": "parcel build ./src/index.html"
  },
  "devDependencies": {
    "@tsconfig/svelte": "2.0.1",
    "parcel-bundler": "1.12.5",
    "parcel-plugin-svelte": "4.0.9",
    "svelte": "3.42.1",
    "svelte-preprocess": "4.7.4",
    "typescript": "4.3.5"
  }
}

To install dependencies using Yarn, copy the code snippet below:

yarn add @tsconfig/svelte parcel-bundler parcel-plugin-svelte svelte svelte-preprocess typescript

Svelte configuration for Parcel

For our Svelte files to contain TypeScript code, we’ll need to specify the Svelte configuration in the ./svelte.config.js file. We’ll use the svelte-preprocess library.

Here is an exemplary configuration script that is compatible with ECMAScript 5:

const preprocess = require('svelte-preprocess');

module.exports = {
    preprocess: preprocess(),
};

TypeScript configuration for Parcel

Let’s configure our application for TypeScript using the partial ./tsconfig.json file below. Your configuration should extend beyond the configuration taken from the @tsconfig/svelte project:

{
    "extends": "@tsconfig/svelte/tsconfig.json",
    "include": ["src/**/*"],
    "exclude": ["node_modules/*"]
}

Now, feel free to test your setup. With these steps complete, you’ve successfully configured Svelte and TypeScript for Parcel.

Choosing the right bundler

As you probably know, bundlers are a rapidly changing technology. Svelte requires a rather extensive integration, so you should always check the behavior of your toolchain when you upgrade dependencies.

Due to the inherent compatibility between Svelte and Rollup, Rollup is a safe choice to use for the durability of your project. Although we can’t say the same for webpack and Parcel, there is always the potential for third-party integration packages to ease the migration from TypeScript to Svelte.

If you use a different bundler, a custom bundler, or no bundler at all, you may need to extensively research the topic on your own and write a custom adapter to allow transpilation in your toolchain. Remember that you need to enable transpilation for both TypeScript and Svelte files.

Conclusion

Although adding TypeScript to a Svelte application may seem self-explanatory due to Svelte’s official support for TypeScript, adding the correct configuration can be quite complex.

In this tutorial, we learned how to configure our TypeScript code for Svelte using Rollup, webpack, and Parcel, three performant bundlers that make it easier to migrate our code.

 

Writing a lot of TypeScript? Signup for our upcoming TypeScript meetup to learn about writing more readable code.

TypeScript brings type safety to JavaScript. There can be a tension between type safety and readable code. Join us on Sept 30th at 2pm EDT for a deep dive on some new features of TypeScript 4.4.

Save your seat.

Gregory Pabian Full-stack software developer who loves building products.

Leave a Reply