Create a node without restart node-red

when I created a node and put it input "/nodes",I must restart node-red to load it. so,Can we have any method to load a node without restart node-red?

Hello,
I'll take the problem the other way around: why wouldn't you want to restart node-red ?

I think if it is possible to enable/reload a node module, why not

I'm used to the notion if I npm install that a restart is necessary. This sometimes stops me doing things till a convenient time (and sometimes that's good) but there have been occasions where I'd wished for this feature to get me out of a hole. E.g. to add some functionality without my flow restarting.

You could just restart Node-Red but that would mean losing Node states !
We could hope for a stageful restart but that leads to a whole bunch of things to be implemented...(https://github.com/node-red/node-red/issues/698#issuecomment-231039213)

Adding functionality on runtime is tricky, not sure of how that could be done generically in Node-red.
(not answering but trying to push discussion forward...)

If you load nodes via the editor (mange palette option) - then they automatically get added to the menu and can be used right away. If you add them manually then the runtime doesn't know about it until you restart and it rescans the directories.

1 Like

Just some brainfarts;

node-red-start -dev 'node-contrib-...'
And then whenever you deploy, it scans the directory of the node(s) in the -dev flag ?

I obviously don't know what this would entail.

Because I don't want to restart the processes that are running, for example, the real-time statistics process.

Node-RED does provide an API that lets to be installed without restarting the process; this is what the palette manager uses in the editor - https://nodered.org/docs/api/admin/methods/post/nodes/

Your node will need to be packaged properly as a module, with a package.json file etc.

It can only be used to install a module - it cannot be used to reload a module already loaded. If you want Node-RED to reload your node because you've changed something, then you must restart node-red. There is no avoiding that.

1 Like

this API is used to install module by npm,but when I create a new node and put it into /nodes,can I have any function to load it without restart node-red?

How does the palette manager do a node upgrade then?

It runs the npm install of the new version and then tells you to restart in order to complete the upgrade.

Oh yes, so it does. Sorry for the noise.

have same problems.

Hi - see Nick's first answer above - Create a node without restart node-red

Node-RED uses Node.JS and npm - so it is constrained by how those work. As others have mentioned, it isn't easy to hot-reload a module since that isn't directly supported by Node.js.

What you can do is to use something like PM2 or Nodemon to monitor the source folder of your node and make Node-RED automatically restart on change.

To get round (partially) the loss of global/flow variables on restart, redefine your default variable store as filesystem instead of memory on your development environment.

1 Like

Hi Nick,

I know, a very old thread...

I have node-red with the admin api disabled.

I want to copy a node (and all deps) into node_modules next to node-red, and then ask node-red to re-scan the node_modules folder.

What are my options, assuming I can call javascript apis from the backend?

br,

Simon

Hi @btsimonh

the external API we have for adding modules also expects to do the npm install part - whether from the public registry, a git url or a tarfile. We don't have a separate API for triggering a 'load this module without doing the install first'.

However, if you are running 2.0, then you can add a preInstall hook to tell Node-RED to skip the npm install part.

RED.hooks.add("preInstall",  (event, done) => {
   // Passing `false` here will tell Node-RED to skip running
   // npm install itself.
   // If you want to be more selective, the `event` object
   // contains details of what is being installed
   // See https://github.com/node-red/node-red/pull/2936
   done(false);
});

With that in place, you can trigger the load of a module using:

RED.runtime.nodes.addModule({
    module: "your-module-name"
}).then(nodeInfo) => {
   // Success!
}).catch(err => {
   // Something went wrong
});

If you are on 1.x, then you don't have the preInstall hook available. It is possible to access more internal code to trigger the loading, but it isn't part of the published API so I'd rather not share that here unless it's really necessary.

Won't it be necessary to update package.json too (if not using npm install), otherwise if npm is used for something else it may remove the folder from node-modules.

Can the API install from a folder rather than a tar file?

Alternatively, perhaps @btsimonh could run a script to use npm to install it from a folder and then call the api to do the rest.

Given @btsimonh said in particular he has copied in the node files and all its dependencies, then I assume the requirement is to not have to touch the npm registry - possibly because its an offline device.

Now I think of it, an alternative would be to add a bundledDependencies property to the node's package.json to list all of its dependencies - and then use npm pack to create a tgz that contains everything you need.

You can then pass that tgz file to the addModule api and it should be able to npm install it entirely locally.

To try that approach, don't add the preInstall hook I described (because we now do want npm install to run), and use the api:

RED.runtime.nodes.addModule({
    tarball: {
        buffer: <a Buffer containing the tarbar contents>
    }
}).then(nodeInfo) => {
   // Success!
}).catch(err => {
   // Something went wrong
});

yep, you are right, I have no npm :). And none of the source is in the local filesystem, all inside multiple VFS packages.

The basics are we build a custom nodejs exe which contains a bootstrapper which pulls down (if not already present) a compressed/encrypted virtual file system, which contains almost everything we need, including node-red (currently 1.0.2).

This is a relatively 'static' package (changed 4-5 times in 4 years).

But now I have a problem with a node (node-red-contrib-mqtt-plus) which is inside that package.

I CAN pull down additional packages, but this is easiest once NR is running, which then merge into the existing VFS. I had always assumed (and maybe true in earlier NR?) that if a flow was loaded that contained an unregistered node, but that the node source was present, that NR would find it. But I tried renaming my node to '...plus-plus', and loaded it in a real device, and no banana.

We have just been hit with another (non NR related) issue where older NodeJS builds do not recognise the new LetsEncrypt cert chain (changed yesterday), so all of my older clients now need to updated to the latest client version anyway (about 400 users). With my latest version I have more options (older versions baked the NR VFS into the exe - all new clients hold it in a separate archive file, making updating it a lot easier). So I will likely sidestep the issue by working on my update code to make that perfect, then force an update, and re-visit the 'load a NR node after run' at a later date.