-
Couldn't load subscription status.
- Fork 3k
Description
What is the issue with the HTML Standard?
Ref web-platform-tests/wpt#55598
Consider this module a.js:
import "unresolvable";When you do import("./a.js") you will get an error thrown because of the unresolvable dependency. What happens if the you re-import it again?
- WPT tests that you will get again the same error ("bad module specifier in a dependency" in dynamic-imports-script-error.html should be updated web-platform-tests/wpt#55598). Historically (before the modules refactoring), when parsing a module we'd immediately try to resolve all of its dependency specifiers, and if any of them failed resolving we'd then store that error as the module's parse error.
- The current spec was changed to do this resolution checking every time ECMA-262 asks to load
./a.js's dependencies, which I didn't realize would be an observable difference. This means that every time we do the dynamic import we will successfully load./a.js(it does not have a parse error anymore!), we will try to resolve its dependencies, and we will generate a new resolution error.
We can update the spec to match again the old behavior, however I'd like to discuss not doing that and instead updating the tests. I have a couple of examples of why I think this makes sense.
1. import source proposal
https://github.com/tc39/proposal-esm-phase-imports allows to do import source of a JS module. It basically means "load this module, but do not load its dependencies yet".
import source of a module with an unresolvable dependency specifier should not throw an error, until when we actually try to complete its processing. For example, we might want to "send" the module to a different environment with different resolution rules (e.g. a worker with a different import map, once they are a thing)
With dynamic import maps, you could even do something like:
const mod = await import.source("./a.js");
installImportMap(); // Make "unresolvable" resolve to something
await import(mod); // resolve mod's dependencies after installing the import mapThis use case could also be solved without re-creating an error every time, and instead storing the resolution error as a "dependencies error" (rather than "parser error") that is only thrown when asking to load a module's dependencies. It would make the new behavior identical to the old one, when using plain import().
2. import re-trying
It seems like there is some recent progress in #6768. If that change ever lands, then it might make sense to allow resolution errors to be re-tried:
await import("./a.js").catch(() => {});
installImportMap(); // Make "unresolvable" resolve to something
await import("./a.js"); // does not throw anymore!Thoughts?