How to use ES6 modules in CommonJS?

Viewed 7145
2 Answers

In Node.js, if you want to import an ES module in a CommonJS module you can use dynamic import and the .mjs file extension on the ES modules. For example:

index.js CommonJS

const crypto = require('crypto');  // to show this is a commonJS module

import('./path/to/mod.mjs').then(mod =>
  console.log(mod.msg);    //  "Hello world!"
);

mod.mjs ES module

export const msg = "Hello world!";

Two examples of how import could be used within a CommonJS module to import all or some of the lodash-es package:

import('lodash-es').then(_ => {
  console.log(_.pad(_.toUpper('hello world'), 17, '*'));
});
Promise.all([
  import('lodash-es/pad.js'),
  import('lodash-es/toUpper.js'),
])
.then(([{ default: pad }, { default: toUpper }]) => {
  console.log(pad(toUpper('hello world'), 17, '#'));
});

Or you can just import what you need into a different CommonJS module then export a Promise which you can then import or require.

utils.js

module.exports = Promise.all([
  import('lodash-es/pad.js'),
  import('lodash-es/toUpper.js'),
]);

index.js

require('./utils.js').then(([{ default: pad }, { default: toUpper }]) => {
  console.log(pad(toUpper('hello world'), 17, '*'));
}); 

ESModules and CommonJS are mutually exclusive, so you can't "use ES6 modules inside CommonJS".

However, in a way, you can "use CommonJS inside ESModules", if by "CommonJS" you only mean the require() function. You can create an instance of require() function with module.createRequire():

import { createRequire } from 'module';
const require = createRequire(import.meta.url);

// sibling-module.js is a CommonJS module.
const siblingModule = require('./sibling-module');

There's a chapter in NodeJS's documentation on interoperability between the two module systems. It's very helpful, you might want to check it out.

Related