# Inheritance of custom nodes (contd.)

**URL:** https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104
**Category:** Developing Nodes
**Created:** [24 August 2021 09:45 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104 "2021-08-24T09:45:47Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![giampiero7](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/giampiero7/32/46927_2.png) [@giampiero7](https://discourse.nodered.org/u/giampiero7)
#### Post date: [24 August 2021 09:45 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/1 "2021-08-24T09:45:47Z")

</div>

I'm continuing on this topic by @H3llsing:

> [@Inheritance of custom nodes](https://discourse.nodered.org/t/inheritance-of-custom-nodes/47282):
>
> Hey there, im writing currently a lot of custom nodes for my company and im interested in a general concept of custom node inheritance. Im dividing my functionality from the ui part. that allows me to use another node as dependency and using its library functions in my new node. But apparently i also want to use some core node functionalities. Like the Schema-Validation of the json node and i do not want to reimplement always functionality into my new node! Does it make sense to you to setup…

Other than the .js file, it would be nice to have the possibility to extend the .html sections too.

Is there anything that could be done as of now to reuse, for instance, `oneditprepare` or `oneditsave` functions from other nodes?

Thanks!

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [24 August 2021 09:56 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/2 "2021-08-24T09:56:46Z")

</div>

> [@giampiero7](#):
>
> Is there anything that could be done as of now to reuse, for instance, `oneditprepare` or `oneditsave` functions from other nodes?

If the functionality is the same then sure. You would need to host the script in a `js` file and use a standard html `script` tag to import it.

---

<div class="post-metadata">

### Author: ![giampiero7](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/giampiero7/32/46927_2.png) [@giampiero7](https://discourse.nodered.org/u/giampiero7)
#### Post date: [24 August 2021 10:11 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/3 "2021-08-24T10:11:52Z")

</div>

Hi @Steve-Mcl ,  
Thanks for the response. I'm talking about importing from a different node, would that work? And how would you point to js from another node in the .html file?  
Thanks!

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [24 August 2021 11:04 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/4 "2021-08-24T11:04:40Z")

</div>

Your other node would present the js file by way on an admin endpoint. Your other-other nodes would use a standard html script tag to import the JavaScript.

Any nodes' server-side js can generate an admin endpoint for resources to be consumed client side. In fact as of node-red 1.3.x you can just place files in a resources folder for it to be served up to the client. All you need then is the URL and you can consume the client side html script tag.

Note. This is all theory as I haven't tested it (but it works in my head - just haven't had a chance to try it out).

Ps, have a look at the js SRC for the serial node to see an example of an admin endpoint.

---

<div class="post-metadata">

### Author: ![giampiero7](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/giampiero7/32/46927_2.png) [@giampiero7](https://discourse.nodered.org/u/giampiero7)
#### Post date: [24 August 2021 14:58 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/5 "2021-08-24T14:58:59Z")

</div>

Thanks again @Steve-Mcl ,  
Adding the .js file in the resources folder seems like a good idea, but it seems to work only if it belongs to an instantiated node. Let me explain:

I'd like to have a library-node that contains the common stuff for all my final nodes. This library-node never gets actually instantiated, as only the final nodes do.  
So, it'd be nice if the resource folder with the common .js files would be only in the library-node module, but since this node never gets instantiated it won't serve the .js files.

Is there an elegant way to achieve this?

Thanks!

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [24 August 2021 20:08 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/6 "2021-08-24T20:08:34Z")

</div>

> [@giampiero7](#):
>
> since this node never gets instantiated it won't serve the .js files.

Well clearly, in order to do something actively, the code has to be run. So if you want to deliver something dynamic, you will need to attach it to Node-RED somehow:

- In an existing node as an API. That node does not actually need to be added to your flow 🙂 Since the act of enabling the node via the palette is enough to load the module which will instanciate the API.
- Loaded to a global in your settings.js - not tried this but it may be possible to access that from a node's config html file.

There are a few other possibilities that I can think of.

In uibuilder, for example, I now have several modules that are singleton classes. That is where the class is instanciated by the module iteself so that there can only ever be a single instanciation of the class. So that instanciated class (because Node-RED is the host, not your node) is now accessible to ANY node's runtime module. Though you do have to take a little care about order of loading. I instanciate the class at the start of my node's runtime module but I don't actually configure it until a bit later on. This makes use of how node.js loads modules. A module is only actually loaded once no matter how many times you `require` it.

Take a look at the source code for uibuilder. Especially, have a look at the v4.2.0 branch code because that has been reworked into a structure that is much easier to follow.

So in the future, someone could write a node that made use of one of the classes as long as they made sure to check that the class instance is actually configured (I provide a gettable flag for that). This would allow another node to make use of the [socket.io](http://socket.io) comms that uibuilder uses for example.

* * *

In theory, you might even be able to use something like that approach but put the initial require in settings.js which would be called even earlier and wouldn't require a node to be in the palette. Not tried that though but I think it should work. The downside of this would be that you would not have any access to any of the Node-RED features since you would be running the class instance before any of the node-red specific code was active.

In addition to the singleton approach, depending on how your code works, you might be able to get away with static methods and variables in a class instead.

---

<div class="post-metadata">

### Author: ![giampiero7](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/giampiero7/32/46927_2.png) [@giampiero7](https://discourse.nodered.org/u/giampiero7)
#### Post date: [25 August 2021 09:51 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/7 "2021-08-25T09:51:26Z")

</div>

Thanks for your input @TotallyInformation ,  
While playing with your suggestions I realised that I was actually wrong: the resource folder of the library-node gets served even if there is no instance of that node.  
All I was missing was the "node-red" element in the library-node's package.json file, which I previously omitted since I thought, having no nodes, there was no need for it.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [25 August 2021 11:41 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/8 "2021-08-25T11:41:22Z")

</div>

Yes, that gives you access to the existing node-red ExpressJS app servers as well as things like access to the node-red settings.

Of course, you could also configure your own separate ExpressJS app as well if you needed to. But I think, in general, if you need to share something into the Editor, it is best to use the existing admin web server as it also aligns the permissions and other security.

It is a fun rabbit hole when you get to look in detail about how node.js modules work, especially in the context of something as complex as Node-RED 😀

---

<div class="post-metadata">

### Author: ![giampiero7](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/giampiero7/32/46927_2.png) [@giampiero7](https://discourse.nodered.org/u/giampiero7)
#### Post date: [30 August 2021 14:44 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/9 "2021-08-30T14:44:02Z")

</div>

Hi all,  
To whoever might be interested, I recently published some nodes on which I tried to push inheritance (if we can call it so) to the max 🙂

Basically, I created a common package that contains all the main logic (server and client side) as well as the HTML templates for the configuration panel and the documentation (help panel):

> **[node-red-contrib-sfera-labs-commons](https://www.npmjs.com/package/node-red-contrib-sfera-labs-commons)**
>
> Common utilities for Sfera Labs Node-RED nodes

Then I created the following Node-RED nodes, which all do basically the same with small differences in the paths of the files they use:

> **[node-red-contrib-sfera-labs-iono-pi](https://flows.nodered.org/node/node-red-contrib-sfera-labs-iono-pi)**
>
> Node-RED nodes for Iono Pi - the industrial Raspberry Pi PLC

> **[node-red-contrib-sfera-labs-iono-pi-max](https://flows.nodered.org/node/node-red-contrib-sfera-labs-iono-pi-max)**
>
> Node-RED nodes for Iono Pi Max - the industrial Raspberry Pi PLC

> **[node-red-contrib-sfera-labs-strato-pi](https://flows.nodered.org/node/node-red-contrib-sfera-labs-strato-pi)**
>
> Node-RED nodes for Strato Pi - the industrial Raspberry Pi server

> **[node-red-contrib-sfera-labs-exo-sense-pi](https://flows.nodered.org/node/node-red-contrib-sfera-labs-exo-sense-pi)**
>
> Node-RED nodes for Exo Sense Pi - Multi-sensor module with Raspberry Pi 4 core

If you check their source code on GitHub, you can see how their .js and .html files have very minimal and similar code, that simply load and call functions and templates from the "commons" package, passing few different parameters.

Let me know what you think of this experiment 🙂

Cheers,  
Giampiero

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [29 October 2021 14:44 UTC](https://discourse.nodered.org/t/inheritance-of-custom-nodes-contd/50104/10 "2021-10-29T14:44:10Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
