Open webJose opened 1 month ago
Isn't createRawSnippet
exactly this?
createRawSnippet
is the API for this, yes. I don't know what we would want to do differently in a .svelte.js
file. If you want to write something that looks like a component, use a .svelte
file. If you want to programmatically create a snippet, use createRawSnippet
.
In the medium term it would be nice to be able to export snippets from Svelte components, perhaps like this:
<script context="module">
export { foo };
</script>
{#snippet foo()}...{/snippet}
There's no intention to create a way to define snippets declaratively outside .svelte
files though. Creating them programmatically with createRawSnippet
is the way to go.
I understand. It is just that the {#snippet}
construct is easier than the raw API. Also, a question (or maybe a point in favor of allowing this): How does one create a snippet with createRawSnippet
that includes a component, not just HTML elements? How would that look like?
And finally, the one other ask I have in my mind is the ability to unit-test the effects of bind:
. I think libraries like @testing-library/svelte
would require a public API that would allow this. I know, different topic, but since I got your attention, I figured I should ask.
Rich's medium term solution would be very good: One could then create .test.svelte component files that define and export the snippets for testing. Then it is a matter of importing them in the .ts/.svelte.ts test file.
Also, I believe this is a duplicate of #11261, which I opened a long time ago, and got downvoted into oblivion. I personally really like the idea but from the community's response it's really not good
@rChaoz I think ppl disliked the syntax maybe not so much the idea
I understand, but the issue has the syntax as a suggestion. The issue itself was to add some way to create snippets in *.svelte.js
files. Anyhow, what would a good syntax be, that's better that the current API?
As Rich is proposing is good enough for me. No need for new fancy syntax, IMHO. Adding the ability to export snippets is an excellent midpoint since component files are not required to have templates or script tags. One can create, today, a snippet-only component file. All we need is the export part.
But can't snippets depend on component props? How to handle that case?
@rChaoz Since snippets are pretty much functions in my head you just have to ensure where you are using that exported snippet just pass the required params
I'm with Antonio: Regular snippets are not for exporting. Exported snippets are exported for a reason. Let it be part of the requirements that they need to be self-contained. Any dependencies, via the parameters.
I understand, my question is: should the following be prohibited? It feels like it would be a huge loss to me. Or, how should svelte figure out whether it can be exported?
My perspective is that context module is for the purpose of having shared state so therefore create a shared state to be used. Not sure if then you can use the new $state.link
rune that’s coming to keep shared state in sync with a parent value passed into the component?
Why would you want to export that snippet? What would be the use case for that? I can only imagine exporting for reuse, if at all. After all, components are superior. I just want exported snippets for unit testing because one consume them in TS/JS files. For application development, I consume from .svelte files, so why would I go the route of snippets when I can go the route of components?
I understand, my question is: should the following be prohibited? It feels like it would be a huge loss to me. Or, how should svelte figure out whether it can be exported?
It's evident that the snippet references a variable defined in the script, so it cannot be hoisted to the context script and exported. The compiler can easily see it.
For curious ones, a close to the proposed solution workaround. Plus, the solution is already proposed in #10350.
Btw i started fiddling around with the changes to allow exporting snippets from the module and i think there's a decent blocker for it: the module is parsed by acorn that errors out if you are trying to export something that is not there. This is also true for the normal script.
So either one limitation is that you can only export a getter for the snippets in the form of function or we should find a way around this error (which seems pretty annoying because you want acorn to error out if you are exporting something that is not there and at the parsing phase we still don't know if the snippet could be hoisted or not).
Wild idea:
{#snippet export foo()}
{/snippet}
Or
{@export foo}
{#snippet foo()}
{/snippet}
Besides the fact that even I dont like the syntax, could the language server even recognize foo
being exported?
Another idea:
<script>
export let snippets = $snippets(foo); // exports object containing passed snippets
</script>
{#snippet foo()}
{/snippet}
Describe the problem
AFAIK, writing snippets outside of Svelte component files is not possible. However, unit testing would greatly benefit from being able to define snippets in .svelte.ts files. Right now, we either create a helper component for the test, or use
createRawSnippet
API.Describe the proposed solution
Be capable of writing snippets in codefiles anywhere (top level, inside function bodies, etc.), as if they were functions or similar.
Importance
nice to have