Create a TypeScript node

I’m working out whether or not to modify the existing Function node to support BOTH JS and TypeScript (via tabs for instance), OR to create a stand-alone node for TS only. I’ll be reusing the code by Steve here:

Any thoughts? What do you think is best?

Hi James,
I proposed tomorrow to create a separate node, because some other developers have done something similar:

But of course yours is a bit different, because Typescript is 'very' related to Javascript...
And I understand your idea of re-using the existing nodes as much as possible ...

normally I don't like if people comment just for the comment's sake, but could you elaborate why you want to have typescript within a function node? I am really curios. I see a reason to use typescript for larger applications where type checking makes sense to rule out bugs, but for small scripts within a function node?

1 Like

No, the core Function node is JavaScript. TypeScript should be a separate node.

We haven't yet had a proper discussion about how to properly move forward with the work Steve has done. His fork is great to show its feasible, but there's lots more work to be done if we want to consider bundling it with the core of node-red alongside, or instead of, ACE.

2 Likes

Well I guess that settles it then, it will be a new node. :wink:

@cinhcet For larger more complicated nodes, having the ability to have better syntax and type checking to help reduce bugs, code completion and refactoring helps to speed up the process. Using Visual Studio to compile, run test, and repeat, is too slow for me, and I was exploring ways to move my existing TypeScript code into an environment where I can test and develop in near real time as possible, and found node-red (I was also exploring low-code solutions). I did think about creating nodes from my TypeScript instead and just using those, but that keeps me in the VS IDE (or even command-line compiling at the least), and I want to get away from that completely if at all possible. Ideally it would be cool to be able to create nodes using TypeScript within code-red for the library instead, otherwise you end up with the same code duplicated across multiple nodes. I'm still thinking that is a better idea, so I may explore that instead.

Is your plan to transpile the TypeScript to JavaScript on save or do you plan to transpile on the fly (ts-node or similar)? Alternatively, if you already have this part working I can just read the code given a link. :slightly_smiling_face:

The plan was to transpile as you edit, and have the JS in another view as well (another tab for instance). That is faster, as the JS already exists then (faster start-up times). My current POC actually just updates the ACE editor with the transpiled code, but Steve's code better integrates with the default editor API.

1 Like

@knolleary I was thinking about it all a bit more more, and realized that having a TS node may node be the best choice for my needs. The better idea would be to have a TypeScript editor create nodes for node-red instead while it is running, so I don't have to keep restarting it to load them (and prevent duplicating the same code). Is it possible to add and remove nodes from the library dynamically while running, or is a restart required no matter what? If dynamic is possible, what would be the best approach? I'm thinking it would be cool to save the TS code and resulting HTML and JS text somewhere within a code-red project, but I don't yet know enough about the core API.

It might not be what you're after but IIRC there is a contributed function node mod that can be configured to read the code from a file (and re-read it if changed).

Hmmm... That could be an idea. Perhaps just keep the node idea and implement a drop-down where I can pick the script I want to execute, then save the scripts somewhere so it can be shared. Does anyone know of a way to save data globally within the project data itself? I'm thinking it would be nice to keep it self-contained within the project instead of having to resort to creating more files.

To me it would sound logical to use the library directory and files already used by Node-RED. The library has a file browser also but it only copies the contents when restoring a script.

Ok, after some more digging I found this:

https://nodered.org/docs/creating-nodes/config-nodes#using-a-config-node

Seems I can just create a TypeScript node and have a global shared "config" node that deals with the coding part separately. That way multiple nodes can share the same code, and the code is saved with the project like everything else. :wink:

While a changed function node doesn't need a full Node-RED restart, it does have to restart at least part of the code because you have to do a deploy. Not sure whether it would be possible to get away without a deploy. I can't think of a realistic way off the top of my head but doubtless someone with more braincells left than I will be able to think of something. It just isn't the current "Node-RED way".

1 Like

I can see the benefit from reloading without publishing while doing development for rapid prototyping of a complex function node, not for production use.

@jamesnw This is the contrib node I didn't remember earlier. It seems to be 3 years old though so I don't know if it works. I haven't tested it in a long while as I've found I still rather write code within Node-RED.

https://flows.nodered.org/node/node-red-contrib-file-function

So to understand you correctly, you want to move existing code into Node-RED?
If you have code that has external dependencies/stores state etc., then in my opinion best to create a custom node for that, if you also plan to have that node more than ones. There it totally makes sense to use typescript.
Some people might say that this is an anti-pattern, but I would argue if the goal is to incorporate existing code into Node-RED then this is the best solution.
The alternative is to recreate the behavior with core nodes, contrib nodes and function nodes.

I just still don't see a reason to use typescript within a function node, since you usually would not write massive amounts of code there, although with v1.1 you get the feature of having setup and closing code for a function node, but you still have to use the context object to share resources between them.

When you install a node from the palette, it is added to the runtime/registry without having to restart Node-RED.
I wonder, would it be a nice developer feature to have "hot-node-module-reloading"? Meaning that if you change some code of a custom node it can be reloaded without having to shutdown Node-RED completely?

1 Like

In simplicity this could be something like being able to deploy "the modified nodes" using a keyboard shortcut while editing a function. I would find it useful for those moments when you write code to parse some input data.

It would certainly be nice not to have to reload the whole of Node-RED each time. Though I can see why Nick keeps his dev environment as clean as possible.

You can, of course, use PM2 or nodemon or similar to automatically restart Node-RED when changes are made. I use that when developing uibuilder.

Hi @jamesnw , I use node-red-contrib-file-function-ext, works fine to avoid [Deploy]

for information : Typescript code can be turn into EXE directly with QuickJS TSC and WASM