Creating a node from ESM module

Hi Devs.
Hoping you can help: I'm only just learning this ESM/ CJS thing.
I'm trying to create a new node-red node based on a module https://www.npmjs.com/package/archer-c7-api,

The module is an 'ESM' but all example nodes I can find appear to be CJS (I think).

I've gone through a world of 'unfulfilled promise errors' or whatever.

The node-red call is async so I thought that I might be able to change the way I load the library but I can't work out what I'm doing wrong.

The example code from the library:

import ArcherC7 from './lib/ArcherC7.js';
(async function() {
const archer = new ArcherC7('http://192.168.1.1','email', 'password', { debug: true });

const devices = await archer.fetchDevices();

console.log(devices);

await archer.logout(); })();

What I'm trying to do in my node.js (haven't included the actual

module.exports = function(RED) {

var C7Devices = (async function(url,user,passwd) {

const A = await import( '../../node_modules/archer-c7-api/lib/ArcherC7.js' );

console.log ("ArcherC7 = ");
console.log ( A );

//  ------?What to do here to instantiate an ArcherC7 object :confused: 
const archer = await new A.ArcherC7('http://192.168.1.1', 'email', 'password', { debug: true });

const devices = await archer.fetchDevices();

console.log(devices);
await archer.logout();
return devices;

})().catch(err => console.error(err));

    function ArcherC7Node(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        node.on('input', function(msg) {
			
			var pass = msg.payload.pass?msg.payload.pass:config.pass;
			var user = msg.payload.user?msg.payload.user:config.user;
			var url = msg.payload.url?msg.payload.url:config.url;
			
			var devices = C7Devices(url,user,pass);
			
            msg.payload = msg.payload.devices();
            node.send(msg);
			
        });
    }
    RED.nodes.registerType("ArcherC7Node",ArcherC7Node);
}

(removed most of the crazy attempt I've made at using this module).

Console output =

ArcherC7 =

[Module: null prototype] { default: [class ArcherC7] }

TypeError: A.ArcherC7 is not a constructor

at C:\Node\Demo\nodes\ArcherC7\ArcherC7.js:22:24

I can't work out how to create the class.

Can anyone suggest what I'm doing wrong? (am I wasting my time?)

Thanks in advance

The whole sorry debacle of CommonJS vs ESM is a complete mess.

For starters, that library ends in .js but node.js normally requires ESM's to end in .mjs - so you have to declare your package to be a module using type: module in package.json.

But then will node-red load a node defined as a module? Not sure as I've not tried it. You would also need to change your node's .js to do an export rather than a module.exports.

I've not used a dynamic import function either I'm afraid so not sure what is going wrong there.

Honestly, that code isn't that long. I would simply copy it into a CommonJS module. It has two dependencies. Axios can be used OK in node.js CommonJS and has an example in the readme to do just that. The other file is just plain JavaScript, you could convert it into another CommonJS module or just include it in the first module.

Thanks,
I was wondering if I had just missed something obvious. I did try changing my node to .mjs or "type":"module" in the package but then node-red complained at startup.
So you are thinking the best way is to re-write the ArcherC7 library module? I can take a look. It's not mine but I might be able to come up with a similar .js module.
Cheers,
Rob

Yup.

It didn't look big so it should be fairly straight-forward.

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