umd bundle for solidjs

I want to render solidjs components in the browser without builder step. For React I do it like this with babel standalone:
<head> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js" crossorigin></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js" crossorigin></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script> <script type="text/babel" id="App.jsx"> window.App = function App() { return ( React.createElement('div', null, React.createElement('h1', null, 'Random header text'), React.createElement('p', null, 'This is a longer paragraph consisting of two to three sentences. It serves as placeholder text to demonstrate how the descriptor handles multi-sentence content. You can replace this with any content you like.'), React.createElement(Userform, {style: {display: 'flex', flexDirection: 'row'}}) ) ); }; window.Userform = function Userform(props) { return ( React.createElement('div', {style: props.style}, React.createElement('label', null, 'Username:'), React.createElement('input', {placeholder: 'Your Github username'}) ) ); }; </script> </head>
Solid also ships babel preset that I could use. The problem is that solid doesn't ship umd bundle, and babel standalone only works with global vars (not esm exports). Any way for me to generate Solid's umd bable myself from sources?
7 Replies
bigmistqke
bigmistqke2mo ago
solid has 2 ways of doing bundleless: solid/h and solid/html. solid/h looks quite similar to react's createElement:
import { render } from "solid-js/web";
import h from "solid-js/h";
import { createSignal } from "solid-js";

function Button(props) {
return h("button.btn-primary", props)
}

function Counter() {
const [count, setCount] = createSignal(0);
const increment = (e) => setCount(c => c + 1);

return h(Button, { type: "button", onClick: increment }, count);
}

render(Counter, document.getElementById("app"));
import { render } from "solid-js/web";
import h from "solid-js/h";
import { createSignal } from "solid-js";

function Button(props) {
return h("button.btn-primary", props)
}

function Counter() {
const [count, setCount] = createSignal(0);
const increment = (e) => setCount(c => c + 1);

return h(Button, { type: "button", onClick: increment }, count);
}

render(Counter, document.getElementById("app"));
solid/html is a tag template literal:
import { render } from "solid-js/web";
import html from "solid-js/html";
import { createSignal } from "solid-js";

function Button(props) {
return html`<button class="btn-primary" ...${props} />`;
}

function Counter() {
const [count, setCount] = createSignal(0);
const increment = (e) => setCount((c) => c + 1);

return html`<${Button} type="button" onClick=${increment}>${count}<//>`;
}

render(Counter, document.getElementById("app"));
import { render } from "solid-js/web";
import html from "solid-js/html";
import { createSignal } from "solid-js";

function Button(props) {
return html`<button class="btn-primary" ...${props} />`;
}

function Counter() {
const [count, setCount] = createSignal(0);
const increment = (e) => setCount((c) => c + 1);

return html`<${Button} type="button" onClick=${increment}>${count}<//>`;
}

render(Counter, document.getElementById("app"));
for these methods you do not need babel or any additional tooling i am a bit confused by your example: you mention you need babel standalone, but then you are using React.createElement directly in the snippet. do you still need babel then? i would assume as long as you don't use jsx you don't need babel?
maxkoretskyi
maxkoretskyiOP2mo ago
thanks for the repsponse, @bigmistqke !
you mention you need babel standalone, but then you are using React.createElement directly in the snippet.
yeah, my bad, it's JSX usually there, so I'd like to compile in browser Solid's JSX using a preset for babbel standalone
bigmistqke
bigmistqke2mo ago
gotcha. in that case: mb you can try out https://esm.sh/babel-preset-solid esm.sh already does a transformation for making things esm friendly
maxkoretskyi
maxkoretskyiOP2mo ago
I managed to put together this, but still there's an error
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Solid JSX with Babel via esm.sh</title>
<script type="importmap">
{
"imports": {
"@babel/standalone": "https://esm.sh/@babel/standalone",
"solid-js": "https://esm.sh/solid-js@1.9.7/web",
"babel-preset-solid": "https://esm.sh/babel-preset-solid"
}
}
</script>
<script type="module">
import * as Babel from 'https://esm.sh/@babel/standalone@7.22.10';
import * as Solid from 'https://esm.sh/solid-js@1.9.7';
import solidPreset from 'https://esm.sh/babel-preset-solid@1.4.0';

window.Babel = Babel;
window.Solid = Solid;
window.solidPreset = solidPreset.default || solidPreset;

Babel.registerPreset('solid', window.solidPreset)
</script>
</head>
<body>
<div id="root"></div>
<script type="text/babel" data-presets="solid">
const {createSignal} = window.Solid;
const {render} = window.SolidWeb;

function Counter() {
const [count, setCount] = createSignal(0);
return (
<button onClick={() => setCount(count() + 1)}>
Clicks: {count()}
</button>
);
}

render(() => <Counter/>, document.getElementById('root'));
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Solid JSX with Babel via esm.sh</title>
<script type="importmap">
{
"imports": {
"@babel/standalone": "https://esm.sh/@babel/standalone",
"solid-js": "https://esm.sh/solid-js@1.9.7/web",
"babel-preset-solid": "https://esm.sh/babel-preset-solid"
}
}
</script>
<script type="module">
import * as Babel from 'https://esm.sh/@babel/standalone@7.22.10';
import * as Solid from 'https://esm.sh/solid-js@1.9.7';
import solidPreset from 'https://esm.sh/babel-preset-solid@1.4.0';

window.Babel = Babel;
window.Solid = Solid;
window.solidPreset = solidPreset.default || solidPreset;

Babel.registerPreset('solid', window.solidPreset)
</script>
</head>
<body>
<div id="root"></div>
<script type="text/babel" data-presets="solid">
const {createSignal} = window.Solid;
const {render} = window.SolidWeb;

function Counter() {
const [count, setCount] = createSignal(0);
return (
<button onClick={() => setCount(count() + 1)}>
Clicks: {count()}
</button>
);
}

render(() => <Counter/>, document.getElementById('root'));
</script>
</body>
</html>
I notcied there's a solid playground, I assume it somehow does the compilatio in the browser?
maxkoretskyi
maxkoretskyiOP2mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
maxkoretskyi
maxkoretskyiOP2mo ago
this worked with h, thanks for the hint
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Solid with h</title>
<script type="module">
import { render } from 'https://esm.sh/solid-js@1.9.7/web'
import h from 'https://esm.sh/solid-js@1.9.7/h'
import { createSignal } from 'https://esm.sh/solid-js@1.9.7'

function Button(props) {
return h('button.btn-primary', props)
}

function Counter() {
const [count, setCount] = createSignal(0);
const increment = (e) => setCount(c => c + 1);

return h(Button, {type: 'button', onClick: increment}, count);
}

render(Counter, document.getElementById('root'));
</script>
</head>
<body>
<div id="root"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Solid with h</title>
<script type="module">
import { render } from 'https://esm.sh/solid-js@1.9.7/web'
import h from 'https://esm.sh/solid-js@1.9.7/h'
import { createSignal } from 'https://esm.sh/solid-js@1.9.7'

function Button(props) {
return h('button.btn-primary', props)
}

function Counter() {
const [count, setCount] = createSignal(0);
const increment = (e) => setCount(c => c + 1);

return h(Button, {type: 'button', onClick: increment}, count);
}

render(Counter, document.getElementById('root'));
</script>
</head>
<body>
<div id="root"></div>
</body>
</html>
still would be good to figure out how to run it with JSX in browser compilation
Simon Chan
Simon Chan4w ago
Just use some normal ES modules
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>Solid JSX with Babel via esm.sh</title>
<script type="importmap">
{
"imports": {
"@babel/standalone": "https://esm.sh/@babel/standalone@7.22.10/",
"solid-js": "https://esm.sh/solid-js@1.9.7/",
"solid-js/web": "https://esm.sh/solid-js@1.9.7/web",
"babel-preset-solid": "https://esm.sh/babel-preset-solid@1.4.0/"
}
}
</script>
<script type="module">
import * as Babel from '@babel/standalone';
import solidPreset from 'babel-preset-solid';

Babel.registerPreset('solid', solidPreset.default || solidPreset)
</script>
</head>

<body>
<div id="root"></div>
<script type="text/babel" data-presets="solid" data-type="module">
import { createSignal } from "solid-js";
import { render } from "solid-js/web";

function Counter() {
const [count, setCount] = createSignal(0);
return (
<button onClick={() => setCount(count() + 1)}>
Clicks: {count()}
</button>
);
}

render(() => <Counter />, document.getElementById('root'));
</script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>Solid JSX with Babel via esm.sh</title>
<script type="importmap">
{
"imports": {
"@babel/standalone": "https://esm.sh/@babel/standalone@7.22.10/",
"solid-js": "https://esm.sh/solid-js@1.9.7/",
"solid-js/web": "https://esm.sh/solid-js@1.9.7/web",
"babel-preset-solid": "https://esm.sh/babel-preset-solid@1.4.0/"
}
}
</script>
<script type="module">
import * as Babel from '@babel/standalone';
import solidPreset from 'babel-preset-solid';

Babel.registerPreset('solid', solidPreset.default || solidPreset)
</script>
</head>

<body>
<div id="root"></div>
<script type="text/babel" data-presets="solid" data-type="module">
import { createSignal } from "solid-js";
import { render } from "solid-js/web";

function Counter() {
const [count, setCount] = createSignal(0);
return (
<button onClick={() => setCount(count() + 1)}>
Clicks: {count()}
</button>
);
}

render(() => <Counter />, document.getElementById('root'));
</script>
</body>

</html>

Did you find this page helpful?