Forem

Cover image for Importing ES 6 Modules from CommonJS
Adam Brandizzi
Adam Brandizzi

Posted on

1

Importing ES 6 Modules from CommonJS

Here at Liferay, a few days ago, we needed to use the p-map package. There was only one problem: our application still uses the CommonJS format, and p-map releases ES6 modules only. Even some of the best references I found (e.g. this post) made it clear that it would not be possible to import ES6 modules from CommonJS.

The good news is that this is no longer true! Using dynamic import, we can load ES6 modules from CommonJS. Let’s look at an example.

In this project, the importer.js file tries to use require() to import an ES6 module:

const pmap = require('p-map');

exports.importer = () => {
  console.log('Yes, I could import p-map:', pmap);
}
Enter fullscreen mode Exit fullscreen mode

Of course, it didn’t work:

$ node index.js 
internal/modules/cjs/loader.js:1102
      throw new ERR\_REQUIRE\_ESM(filename, parentPath, packageJsonPath);
      ^

Error \[ERR\_REQUIRE\_ESM\]: Must use import to load ES Module: /home/adam/software/es6commonjs/node\_modules/p-map/index.js
require() of ES modules is not supported.
require() of /home/adam/software/es6commonjs/node\_modules/p-map/index.js from /home/adam/software/es6commonjs/importer.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 index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/adam/software/es6commonjs/node\_modules/p-map/package.json.

    at new NodeError (internal/errors.js:322:7)
    at Object.Module.\_extensions..js (internal/modules/cjs/loader.js:1102:13)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module.\_load (internal/modules/cjs/loader.js:790:12)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:101:18)
    at Object.<anonymous> (/home/adam/software/es6commonjs/importer.js:1:14)
    at Module.\_compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module.\_extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32) {
  code: 'ERR\_REQUIRE\_ESM'
}
Enter fullscreen mode Exit fullscreen mode

The solution is to convert require() into a dynamic import, a syntax where we invoke the import command as if it was an asynchronous function. But there is one detail: import imports return Promises. There are many ways to deal with this; the simplest one is probably to make our function asynchronous, like in this version:

exports.importer = async () => {
  const pmap = await import('p-map');
  console.log('Yes, I could import p-map:', pmap);
}
Enter fullscreen mode Exit fullscreen mode

Now our little app works!

$ node index.js 
ok
Yes, I could import p-map: \[Module: null prototype\] {
  AbortError: \[class AbortError extends Error\],
  default: \[AsyncFunction: pMap\],
  pMapSkip: Symbol(skip)
}
Enter fullscreen mode Exit fullscreen mode

Some other adjustments may be necessary. (I had to adjust the eslint settings, for example.) The important thing is that this is possible. And it’s not a kludge: Node’s own documentation recommends this approach.

So, don’t be scared by outdated information: you won’t need to rewrite your entire application as ES 6 modules, at least for now. For us, this was quite a relief!https://suspensao.blog.br/disbelief/importing-es-6-modules-from-commonjs/

(Cover image from Wikimedia Commons.)
(The post Importing ES 6 Modules from CommonJS was first published in Suspension of Disbelief.)

Please leave your appreciation by commenting on this post!

It takes just one minute and is worth it for your career.

Get started

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay