After a recent announcement about the use of Svelte, it looked interesting enough to see how easy it might be to use with uibuilder.
As it happens - pretty easy
-
Create a new uibuilder instance and change the url to
svelte
(or whatever you want). Click on Deploy. -
Install the default svelte template to
~/.node-red/uibuilder/svelte
with the commandnpx degit sveltejs/template ~/.node-red/uibuilder/svelte
-
Make some very minor changes to the rollup config: Just change lines 42 and 72 to point to the
dist
folder instead ofpublic
. -
Rename the
public
folder todist
and remove thebuild
sub-folder (it gets recreated).
Note that you will need to restart node-red at some point now - sorry about that, it is the way that uibuilder currently decides whether to serve up the src
or dist
folder. I'll fix that in the future.
- Change the
build/index.html
- noting the leading.
or..
added to the various resources:
<!DOCTYPE html><html lang="en"><head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Svelte app</title>
<link rel='icon' type='image/png' href='./favicon.png'>
<link rel='stylesheet' href='./global.css'>
<link rel='stylesheet' href='./build/bundle.css'>
<script defer src="../uibuilder/vendor/socket.io/socket.io.js"></script>
<script defer src="./uibuilderfe.js"></script> <!-- dev version -->
<script defer src='./build/bundle.js'></script>
</head><body>
</body></html>
And in App.svelte
:
<script>
import { onMount } from 'svelte';
onMount(() => {
uibuilder.start()
uibuilder.onChange('msg', function(msg){
console.info('msg received from Node-RED server:', msg)
nrMsg = msg.payload
})
})
let myGreeting = 'Hello there!'
let nrMsg = ''
</script>
<h1>Svelte + uibuilder</h1>
<p>{myGreeting}</p>
<button on:click={uibuilder.eventSend} data-greeting="{myGreeting}" data-something="this is something">
Click Me
</button>
<pre>{nrMsg}</pre>
-
cd ~/.node-red/uibuilder/svelte && npm install && npm run dev
Note that the dev process creates its own web server but you should ignore that.
-
Now load the uibuilder page with
http://127.0.0.1:1880/svelte/
(or wherever yours ends up)Marvel at the amazing dynamic, data-driven web app you just made!
OK, so not the most amazing thing. But lets note a couple of important points.
-
Make a change to the text in the
App.svelte
page and save it - notice anything on your web page?Yup, it changed without you having to reload it! Just like Svelte's own dev server
-
Attach a debug node to the output of your uibuilder node. Make sure it is set to show the whole msg object. Now click on the button on your page. Notice that you get a message just by clicking the button, no code required (other than the HTML for the button itself).
That uses the new eventSend function in uibuilder v3.2
Note how the
data-xxxx
attributes are sent back to node-red in the payload, one of which is dynamic thanks to Svelte. Also note that themsg.uibDomEvent.sourceId
in node-red contains the text of the button. Try adding an id attribute to the button to see what difference it makes. -
Send a msg to the uibuilder node and note how the payload appears on the page
5 lines of code in total to do that
19 lines of actual code for a simple, data-driven web page. Not too bad I think.
When I get a chance, I will create a GitHub repository with a uibuilder-specific Svelte template to get rid of some of the above steps.
I will also be adding some features to uibuilder in a future release that will make installing your own (or anyone elses) templates to a uibuilder instance. Also, there will be an install
and a build
button. So that most of the above steps will be reduced to a couple of clicks. These changes will help anyone who needs a build step for their web app, not just for Svelte users.