Can not get externalModules to work

I am using Node-Red version 3.1.3 (docker image nodered/nodered:latest) and I fail to get anything related to externalModules to work. I can add modules in function nodes but I can not get any modules to be loaded. There are no signs of the externalModules settings to impact the pallet editor. The only thing I can install using the pallet are from the Community catalogue.

Any ideas what I am missing or what could be wrong?

Can you detail how you come to the conclusion they are not working?
are you getting undefined errors in the function node when trying to use them?

What external libs are you trying to use?
An example export of a function node will help

External Module DO NOT appear in the pallette, they are only exposed to the function node you have set them.

So if you register some-module in a function node.
you will access it in that function node as such.

const SomeClass =  new someModule.SomeClass()

To add to Marcus's questions
Have you enabled externalModules in the settings file?

I get the following on stdout

26 Jan 12:24:14 - [error] [function:67609f45b7b7d590] Error: Cannot find module 'quine-mccluskey-js'

  • /var/lib/homebridge/nodered/node_modules/quine-mccluskey-js

I have entered the module ‘quine-mccluskey-js’ in the function node’s startup form.

Where do this package have to be placed?

There is a lot of information in the default settings.js file regarding externalModules (e.g. regarding the pallet-editor) is this information “wrong”?

In setting.js
Under node settings


    /** Allow the Function node to load additional npm modules directly */
    functionExternalModules: true,

I believe it would be - as I think the ability to add them in the function node is hidden otherwise :thinking:

BUT....

I have a funny feeling that module is... malformed?
The package file does not have a main

and trying it myself I get the same error
I think this is a problem with the module - not Node RED

{
2	"name": "quine-mccluskey-js",
3	"version": "0.3.0",
4	"description": "",
5	"main": "",
6	"keywords": [
7		"quine", "mccluskey",
8		"logical", "expressions",
9		"boolean", "algebra", "logic"
10	],
11	"author": "FellowHashbrown",
12	"license": "MIT",
13	"dependencies": {},
14	"devDependencies": {}
15}

What should “main” point to for it to be valid for node-red? Or is it just enough that it exists?

It should be the entry point for the module - only the developer will know that

This is how I add external modules to my docker instance for use inside the function node.

This example I'm adding xlsx from sheetjs

Get the ID of the node-red container

$ docker ps

Installing npm module (make sure to change the ID to the one you got from $ docker ps)

$ docker exec -it f534d7069634 /bin/bash
$ cd /data
$ ls
$ npm install --save https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz

edit the settings.js file to use this module.

functionGlobalContext: {
         XLSX:require('xlsx'),
    },

now in nodered's function module I can use it like this:

var XLSX = global.get('XLSX');
msg.payload = XLSX.version;
return msg;

I don't like the new system and installing version specific modules has been an issue for me. Until there is a good howto on the new system, installing inside the editor, I'll keep installing modules the old way.

1 Like

I realised that just after sending the question, sorry.
However patching the package.json file made node-red accept the package, and my function node is now working.

Thanks for helping me with the problem.

Any info regarding all the externaModules stuff in the settings.js file that does not seem to be ‘applicable’ ?

Glad you got it working.

But in all honestly, I would raise the issue of the malformed package to the developer.

Instead of having to fix it your self.

And in your use case : doing it at function level seems the easiest

Yes, I have already sent a message to the developer.
My fix was just to see if I could get it to work. In case developer will not respond I will probably make a fork of the project.

Again, anything regarding the info in the settings.js file? Is it wrong, outdated, …?

No - it’s all current.

In settings.js you can:

  • enable/disable the feature to allow function nodes to use / install external modules (as you are doing)

  • add modules at a global level, so all function nodes can see it (regardless of the above setting) but this will require you install the module your self

But note that if you have updated node-red then the settings file will not be updated to the latest version as that could overwrite modifications you have made. There could therefore be obsolete data there.

1 Like

There is a fair amount of settings described on the externalModules { /// … } “object”, what about them?

externalModules
Generally controls what access the pallette menu has (a lot is on by default)

functionExternalModules
Allows / Disallows function nodes to install/use external modules for them self

functionGlobalContext
Exposes modules for all function nodes (Regardless of functionExternalModules)
but this method require that you do global.get("key") in the function node

I'm not sure what you are asking exactly. There are quite a few options available under the externalModules section of the default settings file:

They are all commented out as the runtime applies a sensible set of defaults - but they can be overriden via the settings.

How does this match what is said in the settings.js ?

I think the word external is quite lose here.

external modules in view of the pallette is Node RED nodes that are not part of the core
(i.e 3rd party Nodes)

external modules in view of a function node is any Node JS module (that is on npm for example )

I enabled all these settings but nothing showed up un the pallet manager. Is there some example somewhere where it is described what each of these settings actually do.

I might have the wrong expectations and that could be why I do not experience any effect of these settings. Anything that would clarify would be helpfull.