Elderjs / elderjs

Elder.js is an opinionated static site generator and web framework for Svelte built with SEO in mind.
https://elderguide.com/tech/elderjs/
MIT License
2.11k stars 53 forks source link

Error on build if hydrate-client component is not imported with same name as .svelte file #215

Open kookydev opened 3 years ago

kookydev commented 3 years ago

I've been getting this error on build when I try to hydrate a component on the client:

{ stack: 'ReferenceError: CarouselStaticFunctionality is not defined\n' + ' at /home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/___ELDER___/compiled/components/CarouselStatic.js:1:3242\n' + ' at Object.e [as $$render] (/home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/___ELDER___/compiled/index-1a20a0f2.js:1:1468)\n' + ' at /home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/___ELDER___/compiled/routes/home/Home.js:1:9171\n' + ' at e (/home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/___ELDER___/compiled/index-1a20a0f2.js:1:1468)\n' + ' at render (/home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/___ELDER___/compiled/index-1a20a0f2.js:1:1598)\n' + ' at Object.templateComponent (/home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/node_modules/@elderjs/elderjs/build/utils/svelteComponent.js:24:44)\n' + ' at buildPage (/home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/node_modules/@elderjs/elderjs/build/utils/Page.js:48:40)\n' + ' at processTicksAndRejections (internal/process/task_queues.js:95:5)\n' + ' at async /home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/node_modules/@elderjs/elderjs/build/workerBuild.js:33:50\n' + ' at async Object.asyncForEach (/home/kookopola/Source/zoek-docker-new/ZoekV3/elderwind/node_modules/@elderjs/elderjs/build/utils/asyncForEach.js:9:9)', message: 'CarouselStaticFunctionality is not defined' }

I found that this was happening after importing a component without matching the name of the .svelte file.

For example: import Functionality from './CarouselStaticFunctionality.svelte' throws the above error and the build fails. (Although it works perfectly fine when you're not wanting to hydrate on the client) Whereas: import CarouselStaticFunctionality from './CarouselStaticFunctionality.svelte' works fine for hydrating on the client.

It seems that the componentName prop passed into the svelteComponent() function in elderjs/build/utils/svelteComponent.js is the import name, not the file name, and because it is used in the page.settings.$$internal.findComponent() method along with the folder to find the component, it's looking for a file which doesn't exist.

In an ideal world, the behaviour would match "vanilla" svelte and non-client-rendered elderjs components.

(Edited for better clarity)

nickreese commented 3 years ago

This is a tradeoff that had to be made to make hydration possible with a lightweight implementation. The component names must match the file names otherwise we’d need a full parser to parse the svelte files and figure out the file name from the import.

Totally doable if the juice is worth the squeeze for someone. I’d gladly accept a PR.

The main reason things work this way is we also have the requirement of embedding components just by their name using shortcodes. Some assumptions have to be made in this case.

Hope this makes sense. The docs might be able to be improved on this.

kookydev commented 3 years ago

Makes sense, I thought it might be something like that.

It's no biggie to need to do it that way, as long as it's clear (took me a while to debug, lol). A documentation change should cover it, and perhaps a more informative error message? I'm happy to pitch in with either / both.