Live data from Hacker News

Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

redfin.engineering

51–60 of 152 posts

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#51

Wow, I've been coding JS/Typescript frontends for years and somehow completely missed out knowing anything about CJS & ESM or their differences. I guess it's all irrelevant when you don't use Node, aren't publishing libraries, and are compiling all JavaScript into bundles for deployment and never read the bundled code.

I know how you feel. It really feels like tribal knowledge. You learn this stuff bit by bit from struggles and HN posts. There’s just too much JS stuff out there!

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#53
It's always surprising to read about the trouble this causes for Node. I've been writing mostly Webpack-compiled JS for the past few years, and it seems to allow any random mixture of require and import. Have I just been avoiding trouble areas by chance?

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#54
post #53

It's always surprising to read about the trouble this causes for Node. I've been writing mostly Webpack-compiled JS for the past few years, and it seems to allow any random mixture of require and import. Have I just been avoiding trouble areas by chance?

I do the same. Babel makes life a lot simpler, indeed, but there are still some edge-cases. Especially around tree-shaking, optimization.

And dynamic imports are still complicated sometimes

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#55
post #49
post #37

I’ll conclude with three guidelines for library authors to follow: Provide a CJS version of your library Provide a thin ESM wrapper for your CJS Add an exports map to your package.json This seems like the same fallacy of python’s 2to3, and why they should have written 3to2 instead. If ESM is the new way, library authors should instead have a CJS shim to prevent fossilization of cruft.

> This seems like the same fallacy of python’s 2to3, and why they should have written 3to2 instead. This is incredibly insightful. I'm frankly a bit stunned. I would never have thought of this (and clearly the Python people also didn't) but it is absolutely true. It's also a very transferable strategy for any time compatibility is to be broken. Is this an original thought of yours or do you have references to further…

It's a common refrain when the py2/3 discussions get going. https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#56
post #53

It's always surprising to read about the trouble this causes for Node. I've been writing mostly Webpack-compiled JS for the past few years, and it seems to allow any random mixture of require and import. Have I just been avoiding trouble areas by chance?

Webpack + babel are basically rewriting `import` and `require` calls into their own `__webpack_require__` helper and converting ESM to CJS. Whereas `require` and `import` are node built-ins and `import` is browser built-in. Making stuff interoperate requires some trickery and lax spec compliance.

There are high chances you are relying on some non-spec compliant behaviors but you don't know about it. For example, ESM exports have immutable bindings, which means, mocking exports for unit testing is impossible. If it works for you, it's because you transpile the code from ESM to CJS (either via `babel`, `rewire` or similar tool).

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#57
post #37

I’ll conclude with three guidelines for library authors to follow: Provide a CJS version of your library Provide a thin ESM wrapper for your CJS Add an exports map to your package.json This seems like the same fallacy of python’s 2to3, and why they should have written 3to2 instead. If ESM is the new way, library authors should instead have a CJS shim to prevent fossilization of cruft.

> should instead have a CJS shim

OP wrote, note that it’s easy to write an ESM wrapper for CJS libraries, but it’s not possible to write a CJS wrapper for ESM libraries.

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#58

Wow that was informative. So ES Modules is really about the Red functions [1] getting module support. I find it fascinating watching our understanding of async computation mature over the years. [1] http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...

The last time I asked here why async-await is even a thing, when you can just introduce light/green threads, coroutines, you name it, everyone jumped that it is even better when you mark awaiting points explicitly. Now that it goes from a blog post of some popular language designer, seems no one gonna disagree.

>async computation mature over the years

A good thing, really, but would be much better if the experience from few decades ago wasn't ignored by cool kids who mature.

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#59
post #22
post #20

Earlier quoted context omitted.

> Node does not always fully initialize the dependency module before returning from require(). Unsure what this means. The only reason this happens is because an unfinished copy is provided to the dependency that is causing a circular reference.

It means you can get a half-initialized module back from a require() call.

Does that mean the required modules are not run?

Re: Node Modules at War: Why CommonJS and ES Modules Can’t Get Along

#60

Another issue about module import I encountered before and wasted me 1 hour to find the culprit: When converting TypeScript that using `import default xxx` to JS using `tsc`, it would convert it to something like `exports.default = xxx`. To import it, you have to use `const XXX = require('./mo.js').default` instead of just `const XXX = require('./mo.js')` in plain ES6 JS. This is fine but Babel used to [1] be able to…

Typo: I meant to say "... using `export default xxx`...".
Post reply on HN