3 ms·
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 f
by nosianu 5y ago
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.
- wruza 5y agoEs 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.