4

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.

warahi
  • 41
  • 4
  • 2
    Important question: why? Node [can import either](https://nodejs.org/api/esm.html#esm_interoperability_with_commonjs) as long as your project, and your dependency projects, clearly indicate which flavour of ES they use (i.e. if your code uses ESM, you _need_ to specify `type: "module"` in your `package.json`) – Mike 'Pomax' Kamermans Jul 22 '21 at 21:48
  • @Mike'Pomax'Kamermans Hi Mike. And because I have a file like dataUtils that is used in my frontend applications and also used in my backend api applications. So making it into an npm package for this file makes sense. So I need it to be consumed in CJS when my backend api is consuming it and in ES6 when my frontend apps are using it. – warahi Aug 11 '21 at 05:48
  • No, you don't. You can just write ES6 for both, because Node can import and run ES6 perfectly fine, _even in projects that themselves are CJS_: just set the right values in `package.json` if you're code uses ES modules instead of the legacy commonjs require approach. – Mike 'Pomax' Kamermans Aug 11 '21 at 14:40

1 Answers1

0

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"