I've been trying to improve my developer experience while creating nodes for node-red. Could you guys give me some feedback and help me to improve it?
Features:
- clear separation of client and server pieces of a node. The server side has a Class to shape its form. It provides auto completion.
- directory structure convention. The folder name of a node define its type. All nodes within the src/nodes folder will have its type automatically prefixed. This way, a dev does not need to prefix all his node folders manually. For example, the set of folder names for nodes created to Salesforce like these
-./src/nodes/salesforce-connection,
-./src/nodes/salesforce-crud,
-./src/nodes/salesforce-soql
would be created as
-./src/nodes/connection
-./src/nodes/crud
./src/nodes/soql
But once built, their types would be registered as "salesforce-connection", "salesforce-crud", "salesforce-soql"
This is the directory structure, which would lead to the creation of a node type called "salesforce-connection"
salesforce/
โโโ src/
โโโ nodes/
โโโ connection/
โโโ client/
โ โโโ i18n/
โ โ โโโ dictionaries/
โ โ โ โโโ de.json
โ โ โ โโโ en-US.json
โ โ โโโ docs/
โ โ โโโ de.html
โ โ โโโ en-US.html
โ โโโ icons/
โ โ โโโ icon-1.png
โ โโโ index.html
โ โโโ index.js
โโโ server/
โโโ index.js
- the JS and HTML form of the client side portion are now separate pieces, instead of a single .html. The code highlightning for each language will work without a problem.
- A lib that enables devs to write the server side of the node using ES6 Classes. It has the Node class definition and a mixin that does part of the setup of a node. It is similar to what Salesforce did for the LWC Framework.
- enables modern javascript in both front and backend. The js code you write today, is built for the browser, or node version, of tomorrow without much trouble thanks to ESBuild (I will try rollup too)
- bundling, tree shaking, update js to use modern browser features automatically
- quick development environment using docker-compose, if needed
- sourcemaps for debugging
- builder => possibly a Vite plugin in the future
Once this framework is round, I will try to incorporate it into NR directly.
This is the .html form of a node. No more <script>
tags. The type is defined by the name of the folder. And the registration lines are written automatically for the dev in the final build. This is closer to what modern js frameworks do.
client side js is modular and uses ESM module system. You no longer need to write all your client side JS in a single file. And you can use any of the libraries published in npm registries. The registration is also done automatically by the framework, in the final build. It uses the name of the folder as the type.
As an example for the server side code, the following
export default function(RED){
function Node1(config){
RED.nodes.createNode(this, config);
const node = this;
this.on("input", (msg, send, done) => {
node.log("hello world");
send("something");
}
}
RED.nodes.registerType("node-1", Node1);
}
Becomes this
import { Node } from "@allanoricil/node-red-node";
export default class Node1 extends Node {
constructor(config) {
super(config);
}
onInput(msg, send, done) {
this.log("hello world");
send("something");
}
}
As you can see, a dev no longer has to remember to write RED.nodes.registerType("node-1", Node1);
or that he/she MUST write RED.nodes.createNode(this, config);
before calling this.on
to register event listeners. For those who don't know, if you write this.on
before RED.nodes.createNode
, listeners won't be registered. But in my framework, you don't need to remember it.
Additionaly, while you are writting your node class, because there is a parent class "shaping" your node's class, auto completion features will recommend function names available for you automatically as soon as you type, for example, "on".