Search code examples
javascriptsvelteweb-componentsvelte-3iife

How to compile Svelte 3 components into IIFE's that can be used in vanilla js


I am making a web component in Vanilla JS that use a hidden select in the background and a div and ul>li in front. It became a bit complex with fetching data from an api, ect, so I transitioned to Svelte to simplify it and make it more readable.

Now I've tried for 2 days to export the component as an IIFE. I just can't seem to figure out how. I might be mistaken, but I thought that was one of the main features of Svelte - to make reusable components that can be used anywhere. Making it was the easy part, but now I want to load it and use it directly in the browser (with <script src=""></script>). I thought that should be easy?

I use Svelte 3 (3.57.0) with Vite 4 (4.2.1), and I have tried both npm create svelte to create a library project with SvelteKit and npm init vite with svelte as framework.

I've read quite a lot of the documentation for Vite and Svelte, but it feels overwhelming and I can't seem to find a configuration that works.

Does anyone know how to compile components to IIFEs in Svelte?


Solution

  • By default, SvelteKit only pre-processes components so they can be used by any Svelte project. The Svelte files are then only compiled to plain JS in the projects that use the component library.

    You could add a separate Vite config to fully compile the components to JS files, e.g.

    // vite.js.config.js
    import { svelte } from '@sveltejs/vite-plugin-svelte';
    import { defineConfig } from 'vite';
    import { resolve } from 'path';
    
    export default defineConfig({
        build: {
            lib: {
                entry: resolve(__dirname, 'dist/index.js'),
                name: 'Components',
                fileName: 'components',
            },
            outDir: 'dist-js',
        },
        plugins: [
            svelte(),
        ],
    });
    

    This build operates on the output of SvelteKit which is written to dist and creates a separate JS output in dist-js.

    To run Vite with a specific config you can use the -c argument:

    vite -c vite.js.config.js build
    

    This could e.g. be added as a script in package.json.

    Vite in library mode automatically outputs an ES module file that requires an import and a UMD file which, when no other loaders are in scope, will define the components globally on an object with the name given in build.lib.name.

    So in the above example, if you export Component from the index.js file, you could construct it via new Components.Component({ ... }) with the client-side API.