Live data from Hacker News

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

redfin.engineering

21–30 of 152 posts

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

#21

I haven’t seen CommonJS modules for years now, only ES modules. Didn’t realize this was such an issue still. > You can’t require() ESM scripts That’s one way to put it! Another would be to say that you don’t have to. require() came about because we didn’t have the import keyword.

(Author here.)

You were not using native ESM in Node years ago. Node 14 shipped with unflagged ESM support just this year. (If I had to take a guess, you were probably transpiling "import" statements into "require" statements and/or bundles, which honestly works better than native ESM, because there's no interop issue.)

Almost all of the most depended on NPM packages are CJS, and provide no ESM exports. https://www.npmjs.com/browse/depended

lodash, react, chalk, commander, moment, express, axios, and vue are all CJS.

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

#22
post #20

The description of how require() works is not quite correct. Node does not always fully initialize the dependency module before returning from require(). It can't work that way, because Node allows circular require() dependencies. Try it!

> 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.

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

#23
post #10

JavaScript just gives to much options. I keep having problems with libraries because ES6 allows import x from "library"; import {x} from "library"; import * as x from "library"; import {x as y} from "library"; Just to compare Java uses this: import java.lang.Double; import java.lang.*; No renaming, not a gazillion options during in- and export, but one statement. If you want to rename something, assign it to a variab…

Java's packaging system sucks as does all the similar ones like C#, C++ etc compared to JavaScript's IMO.

All of those the space of namespaces is global. You can't have 2 modules named math.quaterinions in any of those languages. You can in JavaScript. To put it another way, in order to prevent name clashes in C++/C#/Java you have to know the name of every other project on the planet. If someone uses the same namespace then if you ever need to use those 2 projects together one of them will have to be re-factored.

That problem doesn't exist in modern JavaScript. There are no namespaces. There is just floating references to code.

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

#25
post #10

JavaScript just gives to much options. I keep having problems with libraries because ES6 allows import x from "library"; import {x} from "library"; import * as x from "library"; import {x as y} from "library"; Just to compare Java uses this: import java.lang.Double; import java.lang.*; No renaming, not a gazillion options during in- and export, but one statement. If you want to rename something, assign it to a variab…

As a Java programmer dropped into JS land, I totally agree. Keep it simple, one way to achieve something wherever you can. Pythonic, in other words. What I don’t understand is why we didn’t learn from other major languages that had gotten this right already.

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

#26
post #10

JavaScript just gives to much options. I keep having problems with libraries because ES6 allows import x from "library"; import {x} from "library"; import * as x from "library"; import {x as y} from "library"; Just to compare Java uses this: import java.lang.Double; import java.lang.*; No renaming, not a gazillion options during in- and export, but one statement. If you want to rename something, assign it to a variab…

1. Get the default export as x

2. Get the exported value x

3. Get all exported values and call the object x

4. Get the exported value x and call it y

They're all different because they allow you to do different things, and fairly readable.

Edit: Just realised dimgl said the same 45min ago, my bad!

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

#28
post #10

JavaScript just gives to much options. I keep having problems with libraries because ES6 allows import x from "library"; import {x} from "library"; import * as x from "library"; import {x as y} from "library"; Just to compare Java uses this: import java.lang.Double; import java.lang.*; No renaming, not a gazillion options during in- and export, but one statement. If you want to rename something, assign it to a variab…

Java's packaging system sucks as does all the similar ones like C#, C++ etc compared to JavaScript's IMO. All of those the space of namespaces is global. You can't have 2 modules named math.quaterinions in any of those languages. You can in JavaScript. To put it another way, in order to prevent name clashes in C++/C#/Java you have to know the name of every other project on the planet. If someone uses the same namespa…

That’s not true. You can use aliases just fine. .NET is great with this.

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

#29

In two-and-a-half months the last 5 stable releases on Node, the last 2 LTS releases of Node, and all current major browsers will support standard JS modules. It's time we all published standard JS modules and only standard JS modules to npm.

I feel the opposite. ESM is a nightmare and I hope I can avoid using it in node as long as possible.

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

#30
post #10

JavaScript just gives to much options. I keep having problems with libraries because ES6 allows import x from "library"; import {x} from "library"; import * as x from "library"; import {x as y} from "library"; Just to compare Java uses this: import java.lang.Double; import java.lang.*; No renaming, not a gazillion options during in- and export, but one statement. If you want to rename something, assign it to a variab…

1. Get the default export as x 2. Get the exported value x 3. Get all exported values and call the object x 4. Get the exported value x and call it y They're all different because they allow you to do different things, and fairly readable. Edit: Just realised dimgl said the same 45min ago, my bad!

I think people (like the author of this article) should explain the syntax of destructuring assignment {x} briefly to make it make more sense for the unfamiliar.

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Post reply on HN