Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught Error: 'target' is a required option - Svelte

I'm building an NPM package for Svelte. With this package I export a couple of simple components:

import SLink from './SLink.svelte';
import SView from './SView.svelte';

export { SLink, SView };

This is before bundling them to a minified version using rollup.

Rollup config:

module.exports = {
    input: 'src/router/index.ts',
    output: {
        file: pkg.main,
        format: 'umd',
        name: 'Router',
        sourcemap: true,
    },
    plugins: [
        svelte({
            format: 'umd',
            preprocess: sveltePreprocess(),
        }),
        resolve(),
        typescript(),
        terser(),
    ],
};

package.json (minus unnecessary info):

{
    "name": "svelte-dk-router",
    "version": "0.1.29",
    "main": "dist/router.umd.min.js",
    "scripts": {
        "lib": "rollup -c lib.config.js",
    },
    "peerDependencies": {
        "svelte": "^3.0.0"
    },
    "files": [
        "dist/router.umd.min.js"
    ],
}

When I publish the package and test it, I get this error:

Uncaught Error: 'target' is a required option
    at new SvelteComponentDev (index.mjs:1642)
    at new Home (App.svelte:5)
    at Z (router.umd.min.js:1)
    at N (router.umd.min.js:1)
    at new t.SView (router.umd.min.js:1)
    at create_fragment (App.svelte:5)
    at init (index.mjs:1476)
    at new App (App.svelte:5)
    at main.js:7
    at main.js:9

Which seems to be something to do with mounting the component as target is used to mount:

const app = new App({ target: document.body })

The odd thing is, SLink on it's own works fine, mounts as it should etc., it's just SView that doesn't work.

SLink:

<script lang="ts">
    import { writableRoute, changeRoute } from '../logic';

    export let name: string = undefined,
        path: string = undefined,
        query: Record<string, string> = undefined,
        params: Record<string, string> = undefined;

    let routerActive: boolean;

    writableRoute.subscribe(newRoute => {
        if (newRoute.path === '*') return;
        const matches = (path && path.match(newRoute.regex)) || newRoute.name === name;
        routerActive = matches ? true : false;
    });
</script>

<div
    on:click={() => changeRoute({ name, path, query, params })}
    class={routerActive ? 'router-active' : ''}>
    <slot />
</div>

SView:

<script lang="ts">
    import { writableRoute } from '../logic';

    let component: any;

    writableRoute.subscribe(newRoute => (component = newRoute ? newRoute.component : null));
</script>

<svelte:component this={component} />

I've tried the components uncompiled, as per these docs, but then the imports don't work.

Anyone have any idea how I can work around this issue?

like image 409
Daniel_Knights Avatar asked Nov 15 '20 17:11

Daniel_Knights


2 Answers

I recently ran into this problem. I was setting up a new page and forgot the defer keyword on the script. I had:

<script src="/app/public/build/bundle.js"></script>

and it needed to be

<script defer src="/app/public/build/bundle.js"></script>

Notice the missing defer.

like image 133
jjnguy Avatar answered Sep 22 '22 03:09

jjnguy


All components in a Svelte tree need to be compiled with the same Svelte compiler (i.e. same node_modules/svelte) all at once. This includes components from external libs like what you are trying to achieve. This is what is explained in the docs you've linked.

The main field of the package.json will expose the compiled components, for usage in a non Svelte app.

You also need a svelte field to expose the uncompiled version of the components, for consumption by a Svelte app. You can still export multiple Svelte components from a .js file.

package.json

{
    "name": "svelte-dk-router",
    "version": "0.1.29",
    "main": "dist/router.umd.min.js",

    "svelte": "src/index.js",

    "scripts": {
        "lib": "rollup -c lib.config.js",
    },
    "peerDependencies": {
        "svelte": "^3.0.0"
    },
    "files": [
        "dist/router.umd.min.js"
    ],
}

src/index.js

import SLink from './SLink.svelte';
import SView from './SView.svelte';

export { SLink, SView };

rollup-plugin-svelte will pick up the svelte field in your lib's package.json, so that import of Svelte components resolve correctly.

like image 29
rixo Avatar answered Sep 21 '22 03:09

rixo