Zach Posten - 2022 Jul 29
The highs, the lows, the lessons learned
Formsvelte is the first library that I've created for the ever-growing Svelte ecosystem, so I thought I would share some of my takeaways from that experience.
Usually when you first sit down to write a new library, your first hour or two goes into configuring Rollup or some other bundler in a way that suits your needs. I started doing that, only to find out that SvelteKit has built in support for packaging a library! 🎉
I wanted my library to have named exports so that users could import all my components from a single path:
A couple different resources that I found online mention "re-exporting" your components, but it was unclear if I needed an
index.ts file or an
index.svelte file. I wasn't sure how it would work with an
index.svelte file and renaming the default during export didn't work either:
I eventually found that the solution is to first default import your components, and then export them; you can't do both in one step.
I wanted to create a store within the context of a wrapper component and then pass that store down to child components via a slot prop. My thinking was that this could be like Svelte's version of React's render props:
It turns out though that that's not possible. There is this bug on the topic (that was closed in favor of other bugs that seem slightly different to me, but I'm sure the maintainers know what they're doing), and you also get this linting error when you try to do so:
I'm hoping (as the linting error foreshadows) that this does change in a future version of Svelte. But in the mean time, I still haven't figured out how to get around this. It looks like it might be possible to implement Svelte render props as a clunkier version of what I was trying to do with slot props, so that will be the next road I explore.
Svelte has chosen to follow HTML in using
class="" to declare CSS classes, rather than following the React path and using
className="". This is problematic in a JS framework of course because
class is a reserved keyword in the language. In terms of Svelte, that means to allow passing a class to a component, it requires two statements instead of the usual one:
You can't pass class names declared in a Svelte component to a child component without making it global. This seems silly to me. With CSS modules it is perfectly fine to declare a class name in a particular module, import it into a component, and then pass that imported class down to any arbitrary child component. With Svelte's locally scoped class names, the same is not true.
If you haven't tried it yet, take some time and thoughtfully go through the Codecademy style tutorial that the Svelte team has clearly put a bunch of time into creating. It's a really delightful experience and gets you up and running quickly with all the "quirks and features" of the framework.