-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
Describe the bug
I have a server on port 8000 that bundles and hosts svelte components, which are imported into a sveltekit app running on port 5173. This setup used to work fine on svelte 4, but the migration isnt as straight forward as i'd hoped.
Let me show first how the old setup used to work server and client side, and then what ive tried so far.
The server had a esbuild bundler, which had its outputFiles hosted on a http get request.
export default async function bundle (entry) {
const build = await esbuild.build({
entryPoints: [entry],
mainFields: ["svelte", "browser", "module", "main"],
conditions: ["svelte", "browser"],
target: "es6",
format: "esm",
write: false,
treeShaking: true,
sourcemap: config.isDev ? "inline" : false,
minify: true,
bundle: true,
outdir: dirname(entry),
outExtension: { ".js": ".svelte" },
plugins: [
cache(svelteImportMap),
sveltePlugin({ },
compilerOptions: {
filename: basename(entry),
css: "injected",
},
}),
],
});
return build.outputFiles;
}
const svelte = "https://esm.sh/[email protected]";
const svelteImportMap = {
importmap: {
imports: {
svelte,
"@vivalence/ui": `../../../../packages/ui/mod.js`,
"svelte/store": `${svelte}/store`,
"svelte/motion": `${svelte}/motion`,
"svelte/internal": `${svelte}/internal`,
"svelte/internal/disclose-version": `${svelte}/internal/disclose-version`,
},
},
};
....
// serve:
bundler.serve = () => async (ctx) => {
const path = join(dirname(input.path), ctx.params.filename);
const bundle = await bundler(path);
if (bundle) {
ctx.response.body = bundle;
ctx.response.type = "application/javascript";
}
};
This was consumed by the client in two steps.
The Widget functioned as the Sveltekits Universal interface/ loader.
<script>
import Component from "./Component.svelte";
import { onMount } from "svelte";
export let bundle;
export let data;
let component = null;
async function fetchAndCompileAST() {
const response = await locals.call.raw(bundle, null, { method: "GET" });
const text = await response.text();
const blob = new Blob([text], { type: "application/javascript" });
const url = URL.createObjectURL(blob);
const { default: Widget } = await import(/* @vite-ignore */ url);
component = Widget;
}
onMount(() => {
fetchAndCompileAST();
});
</script>
{#if Component}
<Component this="{component}" {...data} />
{:else}
<p>Loading component...</p>
{/if}
The referenced Component:
<script>
import { onDestroy } from 'svelte'
let component
export { component as this }
let target
let cmp
const create = () => {
cmp = new component({
target,
props: $$restProps,
})
}
const cleanup = () => {
if (!cmp) return
cmp.$destroy()
cmp = null
}
$: if (component && target) {
cleanup()
create()
}
$: if (cmp) {
cmp.$set($$restProps)
}
onDestroy(cleanup)
</script>
<div id="game-container" bind:this={target} />
The component thats gettings built by the server is currently an empty demo.
<script>
console.log("Hello World from Component");
</script>
<h1 class="text-palette-white">My Heading</h1>
this setup worked like a CHARM! given, its a bit much, but once i had figured it out, it never had any hickups.
but as you can see, it relied on instantiating the components as new component classes.
now ive updated the build svelte dependency to 5.1.9 which is the same my main sveltekit app uses.
on the client ive tried a few different approaches like:
replace new component with cmp = createClassComponent({component:Component, target }); and cmp = mount(Component, { target, props: payload,});
but nothing works.
I get various error messages like:
Uncaught TypeError: Cannot read properties of undefined (reading 'call')
in Component.svelte
in Widget.svelte
in GameBoard.svelte
in +page.svelte
in layout.svelte
in +layout.svelte
in root.svelte
at get_first_child (operations.js:77:28)
at template.js:48:50
at Flashcards (Flashcards.svelte:3:44)
at render.js:228:16
at update_reaction (runtime.js:317:53)
at update_effect (runtime.js:443:18)
at create_effect (effects.js:125:4)
at branch (effects.js:346:9)
at render.js:210:3
at update_reaction (:5173/.vite/deps/chunk-6CDLSX2F.js?v=6ab23a08:1714:23)TypeError: Cannot read properties of undefined (reading 'call')
at get_first_child (operations.js:77:28)
at template.js:48:50
at Flashcards (Flashcards.svelte:3:44)
at render.js:228:16
at update_reaction (runtime.js:317:53)
at update_effect (runtime.js:443:18)
at create_effect (effects.js:125:4)
at branch (effects.js:346:9)
at render.js:210:3
at update_reaction (runtime.js:317:53)
any help would be welcome. i am very stuck and have no clue what levers to try next.
Reproduction
above
Logs
No response
System Info
System:
OS: macOS 14.5
CPU: (8) arm64 Apple M1 Pro
Memory: 161.06 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.17.0 - ~/.nvm/versions/node/v20.17.0/bin/node
Yarn: 4.5.0 - ~/.nvm/versions/node/v20.17.0/bin/yarn
npm: 10.8.2 - ~/.nvm/versions/node/v20.17.0/bin/npm
pnpm: 9.11.0 - ~/Library/pnpm/pnpm
Browsers:
Chrome: 130.0.6723.117Severity
blocking an upgrade