Live data from Hacker News

ES modules are terrible

gist.github.com

151–160 of 175 posts

Re: ES modules are terrible

#151

Earlier quoted context omitted.

Yes but who cares of native support in the browser? I mean, most JS stuff nowadays is transpiled, written in TypeScript, or if written in plain JS still transpiled anyway to support older browsers, and bundled in a single optimized file. Loading all the dependencies over the network to me is just inefficient, you will have hundreds of requests instead of a single one, you will load the full source not a minified and…

Native support matters so that we're not eternally required to use tools for even the simplest of cases. Being able to write two files with one importing the other with no npm or bundler in sight should absolutely be a feature of the native platform. And yes, in production you probably will want to bundle, but you probably also want to minify. Does that imply that we should require a minifier to even run any code at…

If the project is not so complex, you don't need modules at all. You can just do like we did in the old days (and I still indeed do for simple projects like mostly static sites) and load your JS with `` tags. You can have multiple files, of course everything must be in the global scope to use that but still you can do that.

Re: ES modules are terrible

#152
post #150

Earlier quoted context omitted.

It is not: https://developers.google.com/web/updates/2020/10/http-cache... https://developer.mozilla.org/en-US/docs/Web/Privacy/State_P...

That's the cache in the browser, not the cache in the CDN.

Oh, I see what you’re saying. How could that possibly be exploited for a side channel attack, though? All it would tell an attacker is that someone requested the file before.

Re: ES modules are terrible

#153
i have sympathy for your projects that will need maintenance. but i am making the observation that you're starting to get old - you're being quite bitter over something which is clearly bigger than all of us.

on a personal note, im making a cms with es modules and couldnt be happier.

Re: ES modules are terrible

#154
post #49
post #45

Earlier quoted context omitted.

How browserify, webpack transformers and others are able to parse require()-s in the middle of a source file, but static analysers are not? These subtly erroneous arguments are the essence of this push. Look, we are maintaining X, Y and Z, and they’re unable to do that R, so it’s bad. No, it’s you making them unable to do that consciously.

1) importing module "require()" can take a non-static string. A variable or a string calculated at runtime. You can only statically check if that particular feature is not used, but there is no checking the entirety of what require() can be used for/with. require() is more like dynamic imports in Es modules that are awaited and not like the static ES modules. 2) exporting module The other issue is on the exporting mo…

Es modules that are awaited and not like the static ES modules.

But this is a non-argument. Awaited or not, you can’t statically check them either. Developers aren’t idiots and they can read “if you pass a string to require/import, tooling can’t figure that out” in a manual.

You can statically check “require(literal)” and cannot “require(variable)”. You can statically check “import from literal” and cannot “import(variable)”.

And awaited imports are essentially just memoize(name => (fs.readFile || fetch)(name).then(wrapAndEval)))(name). It’s not a black magic that is available only to “imports”.

do strange things with the "exports" object

It’s just a value. Somehow analyzers/checkers can work with “var x = do_strange_things()”, but can’t with exports. How is a module boundary different from any other expression boundary?

I really don’t want to think that this is pure zealous smoke blowing, but these arguments are as weak as nil, and leave no options.

Re: ES modules are terrible

#155
post #39

Earlier quoted context omitted.

You can detect from the AST whether a require can be statically resolved or depends on non static variables. It may not be as simple, but I venture it's easier to implement than having all the software ever written needing to be migrated

You can detect simple cases like require("some string literal") on top-level. Things become harder if you have require() in init functions or wrapped in (function(){})() or if the module name is defined in a string constant elsewhere. I can't say how common those forms are, but my point is that there is nothing immediately discouraging a programmer from using them as all of it is "just javascript". So even if you jus…

Wrong, things do not become harder when require() is nested somewhere. It may not get called in node, but any bundler looks at it as required-to-be-bundled-anyway. The only case when it’s hard is when require() accepts a non-literal, and that’s symmetric to import(). No extra cases.

The programmer is discouraged to use dynamic requires/imports by the common sense, because that makes their app/lib incompatible with most of the cross-end usage. But then we have server-side only packages like pg or express where it doesn’t matter, because browsers provide no runtime (tcp/listen) for them to function and will never do.

Re: ES modules are terrible

#156
post #31

Earlier quoted context omitted.

Let’s flip this. What are the advantages of ESM that led to selecting that over CJS modules for standardization in the first place?

Statically analyzable tree. In CJS you have to depend on people not doing strange things to their `module.exports` and you are left with heuristics.

Could you please point to “strange things” that people do with “exports” AND how it prevents static analyzers from doing their job? Why they can do it for:

  var x = strange_thing()
but suddenly can not when “x” is renamed to “exports”?

Re: ES modules are terrible

#157

This post is terrible, actually. CommonJS was never going to be natively supported in browsers. The synchronous require semantics are simply incompatible with loading over a network, and the Node team should have known this and apparently (according to members of TC39 at the time) were told their design would not be compatible with future a JS module standard. So the primary thing that JS modules fix is native suppor…

That’s a nice move you do here. Node claimed guilty for implementing the least sucking module system at the time, then growing its NPM size to the skies, and now when there is a ready-to-use module for every task out there, let’s raise a finger and claim they were doing it wrong. Uh oh.

Web standards are goddamn late for 20 (twenty) years and it’s not their moral right to decide what should be broken or deprecated, sitting on the top of the mountain of working code which a workhorse named “node” produced in less than a decade.

Re: ES modules are terrible

#158
post #101

Earlier quoted context omitted.

> - "export already_imported_variable;" - why the HECK is this not in the specification? Having to declare new variable names for exports makes the creation of "index" files so damn painful. This syntax could fix this. You can do: export {already_imported_variable}

...which is a default export, not a named export, as I already explained. My point was about the lack of exporting named exports without the need to declare variable names. Your solution will work only once in a file, therefore it is useless to batch-export lots of imports for the mentioned use case of an "index" file that exports all your classes and definitions.

It isn't default export, as you can see here: https://babeljs.io/repl#?browsers=node16&build=&builtIns=fal...

Re: ES modules are terrible

#159
post #156
post #31

Earlier quoted context omitted.

Statically analyzable tree. In CJS you have to depend on people not doing strange things to their `module.exports` and you are left with heuristics.

Could you please point to “strange things” that people do with “exports” AND how it prevents static analyzers from doing their job? Why they can do it for: var x = strange_thing() but suddenly can not when “x” is renamed to “exports”?

Eg.

    module.exports = {foo: 3};
    setImmediate(() => module.exports[Math.random() > 0.5 ? 'foo' : 'bar'] = 5);

This is impossible for ES modules, because exports are static and known at parse time.

Few widely used packages do something like:

    enhanceWithAdditionalProperties(module.exports, mixin);

Re: ES modules are terrible

#160

Earlier quoted context omitted.

Native support matters so that we're not eternally required to use tools for even the simplest of cases. Being able to write two files with one importing the other with no npm or bundler in sight should absolutely be a feature of the native platform. And yes, in production you probably will want to bundle, but you probably also want to minify. Does that imply that we should require a minifier to even run any code at…

If the project is not so complex, you don't need modules at all. You can just do like we did in the old days (and I still indeed do for simple projects like mostly static sites) and load your JS with ` ` tags. You can have multiple files, of course everything must be in the global scope to use that but still you can do that.

Even simple single-file use cases may benefit from ESM support for top-level await. I thought I had heard of a proposal for supporting top-level await in script mode, but I can’t find it and it probably wouldn’t be feasible anyway because it implies the whole script, which would otherwise be blocking, is async.

That said, nothing is preventing anyone from using type="module" (or .mjs) for uncompiled code. In fact I’m doing this on a project specifically to bootstrap on-the-fly ESBuild TypeScript compilation.

Post reply on HN