SvelteKit Plugins #6708
Replies: 7 comments 11 replies
-
Can you share what the generated
You can use the Vite |
Beta Was this translation helpful? Give feedback.
-
@dominikg @dummdidumm , we talked about it yesterday. 🥳 |
Beta Was this translation helpful? Give feedback.
-
vitejs/vite#11469 has been sent in Vite. Hopefully that will help simplify the Houdini implementation quite a bit |
Beta Was this translation helpful? Give feedback.
-
Hi @AlecAivazis Thanks for your detailed explanation. I would definitely be interested in some sort of plugin system for SvelteKit. 🚀 |
Beta Was this translation helpful? Give feedback.
-
With the new fantastic Zero-effort type safety feature, I would like to bring a bit more attention to this discussion. Yes, as written at the beginning by @AlecAivazis, Houdini generates <script>
- /** @type {import('./$types').PageData} */
+ /** @type {import('./$houdini').PageData} */
export let data
</script> Yes, in the background, Houdini is also generating all types Now, with the new Zero-effort type safety feature, regular kit users will not need to add the type, and that's great! I believe that the plugin system would make it "official" to generate @dummdidumm maybe you could share your view here? 😇 |
Beta Was this translation helpful? Give feedback.
-
Maybe something like that? |
Beta Was this translation helpful? Give feedback.
-
Thanks for sharing ! Is there any way in your opinion to run plugins in isolated contexts almost like in a vm ? for security reasons. I know VS Code uses extensions web host |
Beta Was this translation helpful? Give feedback.
-
👋 Hello! We finally finished updating Houdini to integrate with the latest
+page
design and we had to pull a few different tricks to extend SvelteKit to support what we wanted to do. It occurred to me that what we had built was a kind of unofficial plugin framework for kit so I wanted to open this discussion to gauge interest in the off chance someone has the time to read some thoughts on what a native plugin system could look like for SvelteKit.I tried to find a related issue but couldn’t find anything except for #2611 which sounds like more of an internal organization thing. I think this means that there are realistically 3 scenarios: I missed an issue somewhere; y’all have been thinking about this internally but keeping quiet on purpose; or you have been consciously ignoring it since everything is changing so quickly. Regardless of which, if any, is true, I won’t be upset if you just close this with “too soon” - I totally get it.
The final goal
Before I get into the weeds, it’d probably be helpful to have a general idea what we are doing and why it isn’t really supported by vite’s API (nor should it be). The big challenge was finding a way to implement our inline graphql queries (and
+page.gql
files). Here is an example of a route using Houdini. Just to be clear, this one file is everything the user needs to write for their route to be SSR’d. The+page.js
and load function are generated behind the scenes and totally hidden from the user:Another situation that I struggled with was how to provide our own route-level configuration values exported from
+page.js
. I think this is pretty self explanatory but it was tricky to find a way to reliably look at the exported values of the file. I tried a few different things (some of them lifted from kit’s manifest logic) but ultimately decided that some simple static analysis on the file would be good enough for our constraints.In the end, I came up with solutions for both of these situations but it definitely left me with a not-so-great feeling that what I was doing could be done in a better way.
A new integration point
Before the new design the first situation was relatively straight forward to support with the existing svelte preprocessor api since it just required creating a
module
script in a file that already existed. I think you can probably already see where I’m going with this. In the new world (which i LOVE fwiw), this is significantly harder because we have to fake the existence of a file from the perspective of SvelteKit and vite. The vite part is relatively easy to pull off with theirload
andresolveId
hooks but in order to get Kit to generate the necessary imports for vite to process, the files need to actually exist in the filesystem.This left us with one choice: monkey patching a bunch of functions in
node:fs
to do things like include+page.js
ifreaddirSync
is called on a directory inside ofsrc/routes/...
. It’s not pretty but given the current implementation of Kit, it works surprisingly well. Kudos to @pixelmund for the original idea. If you want to see the actual code, it lives here. I don’t have the exact details in mind, but I suspect basically all of the uncomfortable things we had to do are either things that kit is already doing or is logic that could be avoided all together with the right integration in kit’s manifest and related systems.All of this is to say that I think a SvelteKit plugin can be vite plugin with some extra bits in the same way a vite plugin is fundamentally a rollup plugin.
What would this actually look like?
I think other libraries like svemix or mdsvex would also benefit from something similar but it’s too easy to get caught in never-ending edge cases and “what if”s so I’m only going to talk about houdini’s specific use case. In short, I think the only thing that’s really missing for us is a way to act on a route directory as a whole. I think of this as a fancy version of vite’s
transform
hook. Instead of just giving me the contents of a single file, this new hook would let me look at and transform the contents of a route’s+page.svelte
,+page.js
,+page.server.js
, etc as one. Ideally, the function would also be passed the exported values of+page.js
before transformation which would let plugin authors look for their own route configuration. I have more specific ideas but it’s not worth getting bogged down on implementation details right now. The most important thing is that we have a way to transform files like+page.js
even if they don’t actually exist in the filesystem.Possible Plugins
I’m sure you can already think of some good examples of pluggable bits of logic a user might want to add to their application. In the same way a svelte preprocessor lets people experiment with new syntax and features, this would provide a way for people to try different things using SvelteKit as a base layer. For example, in #6555, someone asked for a way to track when an application has been hydrated. Another example that would be helpful for a wider audience is our recreation of the old session store out of the current primitives. Implementing both of these is pretty straight forward with just the one hook described above. In my mind, this would be a huge step towards achieving a decent boundary that lets kit’s maintainers focus on building a strong foundation while people experiment and go crazy.
Next Steps
Well if you made it this far, thanks for your time ❤️ I think the first big question is whether this kind of extensibility is desirable or not. Assuming that it is, the next question is whether this needs to be in SvelteKit or if it should just exist as an unofficial third party extension. It’s probably worth mentioning that the current implementation does work for transforming routes but I couldn’t find a way to set kit config values from a vite plugin which feels like an easy win. If there was interest in something like this being part of the core framework, I’d gladly give it a shot and submit a PR. Otherwise I will likely pull these bits out of houdini and into a package for others to use. In which case, do you have any ideas for how I could inject additional configuration into kit from my vite plugin? Atm, I force users to manually define a
$houdini
alias which I would love to have hidden from their config file.What do you think? Like I said, I understand this is definitely a post-1.0 thing so I won’t be offended if it’s not worth spending the time thinking through this right now. Just wanted to reach out, say hello, and see if there were any thoughts on what we’ve been doing.
Beta Was this translation helpful? Give feedback.
All reactions