How to use ESM only modules in Custom Nodes?

Because aws-cdk-lib v2 is esm only, the only way I was able to make Node-RED load it was using esbuild to bundle it together with my authored source code. Is there another option?

When I configure esbuild to avoid bundling aws-cdk-lib, esbuild uses require with it and it doesn't work because it is an esm only module. Can Node-RED run an esm build? How can I do it?

I can't have an esm build because then I'm required to use "type": "module" in my custom node package.json because I get this runtime error

Node 18

23 May 19:01:11 - [warn] [node-red-custom-nodes/nodes] Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/allanoricil/node-red-custom-nodes/dist/index.js from /Users/allanoricil/.nvm/versions/node/v18.18.0/lib/node_modules/node-red/node_modules/@node-red/registry/lib/loader.js not supported.

Node 22

23 May 19:03:17 - [warn] [node-red-custom-nodes/nodes] Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'aws-cdk-lib' imported from /Users/allanoricil/node-red-custom-nodes/dist/index.js

The above message for Node 22 is weird because I can see aws-cdk-lib package in ~/.node-red/node_modules

The aws-cdk-lib package is located in ~/.node-red. Neither require nor import can find it at runtime. What could it be?

image

Node-RED can use ESM modules in function nodes.

But for custom nodes, it is more complex and I've still not mastered it. That's because Node-RED is largely CommonJS throughout and so the only way to load an ESM is via the import function which is async.

Thankfully, node.js are finally fixing the ridiculous situation they've allowed to continue for years and give the flexibility to properly load ESM from CommonJS. But that isn't yet live and so probably won't appear in Node-RED until v5.

It would be great to see a way to move custom nodes to ESM, hopefully someone has a clever way.

In the meantime, I do what you are, use ESBUILD to transcribe from ESM to CommonJS where needed. Though honestly, using ESBUILD with node.js modules is a bit of a pain I think and I have no incentive yet to migrate much. I mostly use ESBUILD for front-end code to allow the use of newer JS but build for older browsers.

@TotallyInformation Thank you.
Do you know why Node 22 works with esm but can't find the package still? That is what can't understand. The package is installed in my userDir.

Not sure - is there a node.js version clash? I would have thought it would be a specific error for that.