DEV Community

Why you shouldn't mix ES Modules and CommonJS

Alessio Michelini on June 13, 2023

When working with JavaScript, it's important to follow best practices to ensure smooth and efficient code. One such best practice is to avoid mixin...
Collapse
 
noherczeg profile image
Norbert Csaba Herczeg

It has never been a question about "would you like to, or not", rather a "do I have a choice or not".

Collapse
 
tracker1 profile image
Michael J. Ryan • Edited

In other words, don't use npm. Or only use the parts of npm that fit cleanly into what you have. Or just don't bother to update or change a code base.

As opposed to you know, clearly documenting the edges and making them easier to use.

The fact that Node specifically chose to make thisb harder is what lead to your points. This was done in purpose rather than following the conventions that Babel has in place well before Node added esm support.

Yes, it's closer to the browser convention. But was a half measure from the start and a purposely painful one.

Collapse
 
t_bogard profile image
Erick Rodriguez

You are forgetting scenarios where you need both of them. For example: Angular lazy loading strategy requires you to use require on the endpoint you want to load a component in demand.

It is not that you must not use both of them, but the scenario where you need them

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited

Very good points.

We've ended up with a back end framework where the core stuff is CommonJS but modules that are built into it are ES modules. We ended up supporting both because our modules tend to be colocated with the UI that consumes them (which is all ES modules) and IDE support for refactoring is better for ES modules. At some point we may refactor the whole of the framework too, but that is going to have to sit as tech debt for now as it's rarely touched.

Collapse
 
kerrickchan profile image
Kerrick Chan

I think it's simple. just go to TypeScript other than prototyping or simple scripts.

Collapse
 
noherczeg profile image
Norbert Csaba Herczeg

TS has nothing to do with bundle output formats. You can bundle TS code also in CJS.

Collapse
 
kerrickchan profile image
Kerrick Chan

No, already support for a while. You may bundler other than CJS. it's popular and old. Also, ESM accept CJS but cannot vice versa
typescriptlang.org/docs/handbook/e...

Thread Thread
 
noherczeg profile image
Norbert Csaba Herczeg

What I said is, mixing TS into the topic is pointless because it can produce any output format.

Thread Thread
 
franzzemen profile image
Franz Zemen

BTW, CJS can load ESM with dynamic import. To get TS types use the import type syntax.

And..the article above makes claims without proof. Know your language, i.e understand the why of things and intermixing CJS and ESM, if needed, becomes straightforward.

Collapse
 
hassansuhaib profile image
Hassan Suhaib

I was working with NestJS on a project and there was library that I desperately needed but it only supported CommonJS so my code was crashing. Took me quite a while to fix that.

Collapse
 
malgorzataxkowal profile image
malgorzataxkowal

I face a similar problem. I'm using esm modules but for some reason lighthouse library (only parts- startFlow function) can not be imported cause of incorrect type [stackoverflow.com/questions/777223...]