Hacker News new | ask | show | jobs
by wruza 1685 days ago
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 comments

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 module's side: You can do strange things with the "exports" object. ES module exporting is more strict to make it guaranteed statically analyzable.

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.