Is there a way to create a module that can be consumed by both ESM and CJS applications?

Viewed 687

I have a backend CJS application & a frontend ESM application. And a node module I have created in ESM. The node module works fine for my ESM application because they are both using ESM import syntax. Trying to consume it in the CJS application obviously throws errors as it cannot read the ESM import syntax.

I've tried using Rollup.js to convert the ESM code into CJS and using conditional exports in my package.json file but this does not work.

1 Answers

Assuming it is a library like:

my-library.js

// No require on top. They will be local to their use.
const myLibrary = ...

// export default instead of module.exports
export default myLibrary

The library must first have its extension rename to .mjs ("my-library.js" = "my-library.msj")

Then,

in CJS (Node.js) =>

Dynamic import:

const {default: myUtilityLib } = await import("./my-library.mjs");

In ESM (Browser) =>

Standard import as usual:

import myUtilityLib from "./my-library.mjs"
Related