Error [ERR_REQUIRE_ESM]: Must use import to load ES Module

When starting node-red I am getting following error in log file:

Welcome to Node-RED
===================
1 Sep 19:20:36 - [info] Node-RED version: v1.1.3
1 Sep 19:20:36 - [info] Node.js  version: v12.18.3
1 Sep 19:20:36 - [info] Linux 4.18.0-193.6.3.el8_2.x86_64 x64 LE
1 Sep 19:20:37 - [info] Loading palette nodes
1 Sep 19:20:38 - [info] mDashboard version 2.19.4-beta started at /mui
1 Sep 19:20:38 - [info] Dashboard version 2.23.2 started at /ui
1 Sep 19:20:38 - [info] Settings file  : /data/settings.js
1 Sep 19:20:38 - [info] Context store  : 'default' [module=memory]
1 Sep 19:20:38 - [info] User directory : /data
1 Sep 19:20:39 - [info] Server now running at http://127.0.0.1:1880/
1 Sep 19:20:39 - [info] Active project : node-red-...e
1 Sep 19:20:39 - [info] Flows file     : /data/projects/n...e/flow.json
1 Sep 19:20:39 - [info] Starting flows
1 Sep 19:20:39 - [error] [staticMarkdown:fd547745.e3b158] Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /data/node_modules/@gerhobbelt/markdown-it-attrs/dist/markdownItAttrs.js
require() of ES modules is not supported.
require() of /data/node_modules/@gerhobbelt/markdown-it-attrs/dist/markdownItAttrs.js from /data/git/node-red-contrib-static-markdown/nodes/lib/serveMarkdown.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename markdownItAttrs.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /data/node_modules/@gerhobbelt/markdown-it-attrs/package.json.
1 Sep 19:20:39 - [info] Started flows

Note that I don't have this error on my other docker environment that is using Node.js version v10.22.0
FYI this is what is logged on my other environment:

Welcome to Node-RED
===================

1 Sep 17:25:25 - [info] Node-RED version: v1.1.3
1 Sep 17:25:25 - [info] Node.js  version: v10.22.0
1 Sep 17:25:25 - [info] Linux 4.19.76-linuxkit x64 LE
1 Sep 17:25:25 - [info] Loading palette nodes
1 Sep 17:25:25 - [info] Settings file  : /data/settings.js
1 Sep 17:25:25 - [info] Context store  : 'default' [module=memory]
1 Sep 17:25:25 - [info] User directory : /data
1 Sep 17:25:25 - [warn] Projects disabled : editorTheme.projects.enabled=false
1 Sep 17:25:25 - [info] Flows file     : /data/flows.json
1 Sep 17:25:25 - [warn] 

---------------------------------------------------------------------
Your flow credentials file is encrypted using a system-generated key.

If the system-generated key is lost for any reason, your credentials
file will not be recoverable, you will have to delete it and re-enter
your credentials.

You should set your own key using the 'credentialSecret' option in
your settings file. Node-RED will then re-encrypt your credentials
file using your chosen key the next time you deploy a change.
---------------------------------------------------------------------

1 Sep 17:25:25 - [info] Starting flows
1 Sep 17:25:27 - [info] [serveMarkdown] Mounted /remote/node-re....e/docs on /docs/
1 Sep 17:25:27 - [info] [serveMarkdown] Mounted /remote/node-red-contrib-static-markdown/docs/test-md-library on /docs2/
1 Sep 17:25:27 - [info] Started flows
1 Sep 17:25:27 - [info] Server now running at http://127.0.0.1:1880/

The problem is due to the installation of branch https://github.com/janvda/node-red-contrib-static-markdown/tree/redirect-to-index.md
To install that branch, I have cloned it in my docker container and I have installed it by the command:

cd /data; npm install git/node-red-contrib-static-markdown

Thanks to docker, I can quickly check with different versions:

So the issue is seen in docker versions:

  • nodered/node-red:1.1.3-12 (= Node.js version: v12.18.3)
  • nodered/node-red:1.1.2-12 (= Node.js version: v12.18.2)
  • nodered/node-red:1.1.0-12 (= Node.js version: v12.18.1)

I don't have the issue for following docker version:

  • nodered/node-red:1.0.0-12 ( = Node.js version: v12.10.0)

I have seen a number of links referring to recent node.js version that is doing extra checking which causes this error:

I won't have the definite answer for you but have you set a fixed version for the "offending" Node package (or the one depending on it)? This looks similar to the recent drama with is-promise adding support for ES modules: https://news.ycombinator.com/item?id=22979245

I'm thinking if the new container fetched a newer semver version of the package if it's not fixed.

Ah but the thread you linked says Node 12.11 added ES module support by default, so likely the package is then attempted to import as an ES module in a context where it's not supported. (Yes I know this is a huge mess.)

I didn't reinstall the package on the different docker versions so that doesn't explain the difference. (packages are installed in /data volume so they are not overwritten by docker image).

Moreover the problem package is:

  "dependencies": {
    "@gerhobbelt/markdown-it-attrs": "^3.0.3-19",

which is the latest version from that repository.

As workaround I have used:

  "dependencies": {
    "markdown-it-attrs": "^3.0.3",

as this one doesn't make use of ES modules.

I would see this as a problem with Node.js or the markdown module and not with Node-RED docker image?

Yes, I agree that it is not an issue with the docker image. I have only used the different docker images to demonstrate that the problem appears when using recent Node.js version but not for older Node.js version.

It seems indeed an issue with that module.
I have created the node.js program from the readme:

bash-5.0$ cat /data/test.js
var md = require('markdown-it')();
var markdownItAttrs = require('@gerhobbelt/markdown-it-attrs');

md.use(markdownItAttrs, {
  // optional, these are default options
  leftDelimiter: '{',
  rightDelimiter: '}',
  allowedAttributes: []  // empty array = all attributes are allowed
});

var src = '# header {.green #id}\nsome text {with=attrs and="attrs with space"}';
var res = md.render(src);

console.log(res);


bash-5.0$

and when I run that program (using node.js version v12.18.3) I am also getting the error:

bash-5.0$ node test.js
internal/modules/cjs/loader.js:1153
      throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
      ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /data/node_modules/@gerhobbelt/markdown-it-attrs/dist/markdownItAttrs.js
require() of ES modules is not supported.
require() of /data/node_modules/@gerhobbelt/markdown-it-attrs/dist/markdownItAttrs.js from /data/test.js is an ES module file as it is a .js file whosenearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename markdownItAttrs.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /data/node_modules/@gerhobbelt/markdown-it-attrs/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:13)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at Module.require (internal/modules/cjs/loader.js:1025:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/data/test.js:2:23)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14) {
  code: 'ERR_REQUIRE_ESM'
}
bash-5.0$

Maybe the same exact issue as the infamous is-promise case?

Post-mortem from the module developer https://medium.com/javascript-in-plain-english/is-promise-post-mortem-cab807f18dcc

1 Like

I don't know if it is anything to do with the problem but you appear to have installed both mdashboard and the standard dashboard. They are incompatible so I suggest removing one of them and seeing if it makes a difference.

@janvda, is there a reason to be using your own fork of my node? Isn't there something that can be merged back into the main node?

@TotallyInformation I am using the own fork just for testing the changes I have made. I have already raised 2 pull requests for merging those changes back into the main node. The 2 pull requests won't introduce this issue, so for me it would be great if you could merge them. If anything more is needed I am happy to hear it from you.

Oops, been rather distracted this year. I'll go look. Thanks.

OK, I've now merged all of the outstanding PR's. I haven't had time to test them but you seem to have been comprehensive in documenting things and I'll assume you've tested them well enough :mage:

I've also closed the Issues you raised since I think they were all dealt with by your PR's - please feel free to reopen any that weren't.

I'll try to do a quick test tomorrow and then I'll publish a new version to npm.

Many thanks for contributing to this node & I'll add you to the contributors before I publish. Feel free to suggest any further enhancements.

1 Like

I have updated all of the outstanding dependencies. This means that the minimum node.js version is now v10 so I've bumped the version to v0.1.0 to make it clear that this version has potentially breaking changes.

Could you please test in your environment to make sure it all works for you? I've pushed the changes to GitHub master.

If breaking it should really be a major version bump. So 1.x

Pre v1 you can bend the rules :stuck_out_tongue:

True, but we know there are users out there still on node 8.

Ah. Good point Dave.

Actually, I wonder if Julian has specified a minimum node version in the package.

And now I wonder if specifying min engine will even work with only a minor version bump :thinking:

Julian has indeed done that and has specified a minimum Node-RED version too :wink:

Dave, it was a 0.0.x version previously and my understanding of the "rules" is that 0.0 to 0.1 is considered breaking. Not sure that the code is really v1 quality to be honest even after some TLC from @janvda

Anyway, I spotted a couple more issues buried away and an issue related to the module dependency updates so I've fixed those and you now have a v0.1.1

I'd be grateful if a few people would install from GitHub and try it out. It seems to be working for me.

BTW, trying to get a diagram plugin for markdown-it has been driving me MAD! There are quite a few on npm but none of them work, some don't have GitHub entries backing them any more and the ones that might work all require a build step because they all use import statements instead of require. Very frustrating.

2 Likes