Migrating an NX workspace to use ESM

312 views Asked by At

I have a big NX based monorepo, half a dozen apps, frontend, backend, dozens of libs. It's all still setup to work with commonjs module types, which is what the NX generators produced always, and still do.

However more and more libraries release "ESM only"-versions, which straight up do not work at all for this monorepo.

I just completed nx migrate latest, am on NX 17, Typescript 5.2, Angular 17, but commonjs just seems to stay where it is.

Attempts to upgrade by hand have all failed, everytime I fix one error the next one comes around, often requiring large scale changes over 1k+ imports or hundered of files with uncertain outcomes.

Is there any documentation I am missing anywhere for how to migrate?

2

There are 2 answers

0
jakob fra fyn On

I am looking for a way to do this!

For now I decided that the time has not come yet, and to hope for a solution from Narwahl instead of manually updating a bunch of files.

As a mere reader of stack overflow, I'm not supposed to vote for a question it seems.

0
Carlos Esteban Lopez Jaramillo On

Aafik the best way to support ESM and CommonJS modules at the same time is using TypeScript, which allows for both and will bundle the CommonJS and ESM dependencies with allowSyntheticDefaultImports and esModuleInterop.

https://www.typescriptlang.org/docs/handbook/modules/appendices/esm-cjs-interop.html

Now that doesn't mean it works everywhere, for example NodeJS projects usually don't bundle dependencies, instead opt into bundling the app code and then installing the dependencies every time, specifically because some dependencies rely on install time hardware/OS level checks to compile code for performance reasons, or to use specific hardware capabilities like GPU.

The article in the TS docs also mentions Interop in NodeJS, and the gist of it is that you can't require a true ESM, which doesn't matter for us since we want our src in true ESM.

https://www.typescriptlang.org/docs/handbook/modules/appendices/esm-cjs-interop.html#interop-in-nodejs

If I get this correctly, for NodeJS > 16 if you define in package.json the "type": "module" NodeJS will assume your codebase is ESM, and with esModuleInterop it will import CommonJS modules with no problem, the issue is when your code is not true ESM and it tries to import true ESM.