S
SolidJSβ€’6mo ago
Puru

React.createElement equivalent?

Trying to make a little library which exports a component. The component's JSX is simply return <div ref></div>, hence i'd prefer not to use JSX itself, to simplify the build pipeline. Is it possible to do so without JSX?
32 Replies
Jasmin
Jasminβ€’6mo ago
You should be able to use document.createElement. In solid, every element is literally just a DOM element. But I think this could get tricky with typing it properly, it's usually not the way to go for. Another option is to use the Dynamic component from solid.
thetarnav
thetarnavβ€’6mo ago
this would also work for ssr
Jasmin
Jasminβ€’6mo ago
true document.createElement could cause problems
thetarnav
thetarnavβ€’6mo ago
also it’s just better to use a template, so it could be compiled, even if you don’t necessarily need to
Jasmin
Jasminβ€’6mo ago
oh wait I know you @Puru ! :D Are you porting neoconfetti to solid? 😁
Puru
Puruβ€’6mo ago
Yes 😁
Jasmin
Jasminβ€’6mo ago
awesome!
Puru
Puruβ€’6mo ago
SSR is not an issue, the usage would look something like {condition && <Confetti />}, as confetti explodes the second its mounted I was gonna reach for document.createELement, but was holding out in case there's a solid specific way the library does all the DOM creation in plain JS, so solid's reactivity isn't needed at all either
Jasmin
Jasminβ€’6mo ago
can you be sure that this will never be SSR'd? If condition is true initially, it will.
Puru
Puruβ€’6mo ago
In that case, it would take one tick of event loop to create the element, after solid makes everything, which means confetti is delayed by roughly 16ms(or 8) That seems to be the worst case here Gotta test it in SolidStart first though, to see if it works But that doesn't help with JSX part, right?
Jasmin
Jasminβ€’6mo ago
No, but there isn't really another way in Solid. I would stick with <div ref></div>, it's the simplest way.
Puru
Puruβ€’6mo ago
This is the React version. Solid version should be identical to this, see how in the end its React.createElement, instead of the usual JSX
No description
Puru
Puruβ€’6mo ago
One question: If I transpile solid's JSX down to plain old JS, and ship that, will that work after being imported? Or does Solid requires JSX only?
Jasmin
Jasminβ€’6mo ago
it works but can cause issue with SSR environments πŸ™ˆ That's why solid packages often provide an additional solid export where the user can access jsx files https://github.com/corvudev/corvu/blob/main/packages/corvu/package.json For example like here
Jasmin
Jasminβ€’6mo ago
No description
Puru
Puruβ€’6mo ago
I would prefer the use: way more, but that is a PIA when used in TypeScript, had a conversation with Ryan Carniato about that when I made @neodrag/solid. Ohh
Jasmin
Jasminβ€’6mo ago
because if your package got compiled to js with another solid version than the user uses, it can result in issues
Puru
Puruβ€’6mo ago
SolidJS itself won't be included in the final build, the imports from Solid will stay Or does the compiled output differ from version to version? πŸ€”
Jasmin
Jasminβ€’6mo ago
yes it can
Puru
Puruβ€’6mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Puru
Puruβ€’6mo ago
Seems i can import $template directly and return that?
Jasmin
Jasminβ€’6mo ago
hmm in your react code, doesn't the confetti instance get destroyed on every options update?
Puru
Puruβ€’6mo ago
No, I checked for that Apparently the destroy function runs only when the component is destroyed
Jasmin
Jasminβ€’6mo ago
hmmm
export function Confetti(props: ConfettiProps) {
const [ref, setRef] = createSignal<HTMLElement | null>(null)
let confettiInstance: any

createEffect(() => {
if (!confettiInstance) {
confettiInstance = confetti(ref(), props.options)
return
}
confettiInstance.update(props.options)
})

onCleanup(() => {
confettiInstance.destroy()
})

return <div ref={setRef} class={props.class} />
}
export function Confetti(props: ConfettiProps) {
const [ref, setRef] = createSignal<HTMLElement | null>(null)
let confettiInstance: any

createEffect(() => {
if (!confettiInstance) {
confettiInstance = confetti(ref(), props.options)
return
}
confettiInstance.update(props.options)
})

onCleanup(() => {
confettiInstance.destroy()
})

return <div ref={setRef} class={props.class} />
}
This would be the solid implementation.
Puru
Puruβ€’6mo ago
Ughh the output seems to differ from client-side to server-side to universal
Jasmin
Jasminβ€’6mo ago
you don't really need to worry about that. There is an esbuild plugin which can create js from solid jsx and if you export the jsx source code additionally it will work for everybodys environments
Puru
Puruβ€’6mo ago
Ohh I am using esbuild for the bundling
Jasmin
Jasminβ€’6mo ago
npm
esbuild-plugin-solid
Solid's integration for ESBuild. Latest version: 0.5.0, last published: a year ago. Start using esbuild-plugin-solid in your project by running npm i esbuild-plugin-solid. There are 4 other projects in the npm registry using esbuild-plugin-solid.
Puru
Puruβ€’6mo ago
This seems nice
Puru
Puruβ€’6mo ago
Hmm this is a problem
No description
Puru
Puruβ€’6mo ago
Im trying to keep the sizes as low as possible, this seems too much Kay IG Ill ship the directive version only then πŸ˜… Its one extra line of code for the user but keeps the sizes very very small
Puru
Puruβ€’6mo ago
Heya Im releasing it as a directive only. Simplest for me, and wont cause any troubles during rendering either https://github.com/PuruVJ/neoconfetti/pull/22