importmap fails to map imports for external scripts when the scripts are served locally.
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox116 | --- | fixed |
People
(Reporter: 1679278, Assigned: allstars.chh)
References
Details
Crash Data
Attachments
(5 files)
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:107.0) Gecko/20100101 Firefox/107.0
Steps to reproduce:
dom.importMaps.enabled
= True
thisworks.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>This will work</title>
<style>
body { margin: 0; }
</style>
<script type="importmap">
{
"imports": {
"three": "https://cdn.skypack.dev/three"
}
}
</script>
</head>
<body>
<script type="module">
import * as THREE from 'three';
console.log("THREE has been imported:", typeof THREE);
</script>
</body>
</html>
bug.js
:
import * as THREE from 'three';
console.log("This doesn't work:", typeof THREE);
thisdoesnotwork.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>This will NOT work</title>
<style>
body { margin: 0; }
</style>
<script type="importmap">
{
"imports": {
"three": "https://cdn.skypack.dev/three"
}
}
</script>
</head>
<body>
<script type="module" src="bug.js"></script>
</body>
</html>
Actual results:
The inline script works fine, but the sourced script does not recognise the mapped imports.
Expected results:
Both cases should have worked.
The specific error message in the console is:
Uncaught TypeError: The specifier “three” was a bare specifier, but was not remapped to anything. Relative module specifiers must start with “./”, “../” or “/”. bug.js:1:23
Comment 2•1 year ago
|
||
The Bugbug bot thinks this bug should belong to the 'Core::DOM: Core & HTML' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Updated•1 year ago
|
Updated•1 year ago
|
Assignee | ||
Comment 3•1 year ago
|
||
Hi,
I have met this before, if the external module script is from a local HTTP server, because Gecko will do speculative parsing, so the module script will be preloaded before the import map is loaded, therefore the specifier couldn't be resolved.
If the HTML is hosted on a remote server (github in my example) then the problem went away.
Do your test pages (HTML and bug.js) come from a local HTTP server?
Thanks
(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #3)
Do your test pages (HTML and bug.js) come from a local HTTP server?
Yes.
As I understand, this is a race condition then?
Assignee | ||
Comment 5•1 year ago
•
|
||
(In reply to A from comment #4)
As I understand, this is a race condition then?
Yes, because the module script will be preloaded by speculative parser, but the import map script tag won't.
The preloading of import-map will be done in Bug 1762595, but it needs to be implemented together with external import-maps. (Bug 1765745).
Please try to host your scripts/HTMLs in a remote web server, if the problem still exists, please provide the URL so I can test it as well.
(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #5)
Please try to host your scripts/HTMLs in a remote web server, if the problem still exists, please provide the URL so I can test it as well.
Very nice catch!
- I have tested on a remote web server and the problem goes away. 👍
- If I test locally via
python -m SimpleHTTPServer
or similar the problem manifests itself, as reported. 👎 - If I test locally via `ssh -L8001:localhost:443 remoteserver.example.com (and accept the certificate warning) the problem still goes away (because of latency?). 👍
- All of the above is still true if I change the import map as follows (so that it imports from the same server): ✔
<script type="importmap">
{
"imports": {
"three": "/three.module.js"
}
}
</script>
Assignee | ||
Comment 7•1 year ago
|
||
Thanks for the clarification.
I'll duplicate this bug with Bug 1762595, as this problem should go away when we have speculative parsing of import-maps.
Comment 8•1 year ago
|
||
(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #5)
Yes, because the module script will be preloaded by speculative parser, but the import map script tag won't.
This seems bad for developers as it's easy to trigger this problem and not obvious what's going on.
Is there some way we can fix this? The spec says to disallow futher import maps when a module script is fetched. Can we delay this while we're preloading?
Assignee | ||
Comment 9•1 year ago
•
|
||
(In reply to Jon Coppeard (:jonco) from comment #8)
This seems bad for developers as it's easy to trigger this problem and not obvious what's going on.
Is there some way we can fix this?
See Bug 1762595 for details, we could preload import-maps, but that will also bring other problems, like https://bugzilla.mozilla.org/show_bug.cgi?id=1762595#c7
and https://github.com/WICG/import-maps/issues/281
Because speculative parsing is implementation-dependant and external import-maps isn't supported now so we don't preload import-maps yet (As there is other corner-case like <modulepreload>)
The spec says to disallow futher import maps when a module script is fetched. Can we delay this while we're preloading?
In our implementation, if the module load is of type preload, we won't disallow import-maps, otherwise import-maps won't work because we will preload modules.
See https://searchfox.org/mozilla-central/rev/a44deb21744de6269329b05461c55488a147f95e/dom/script/ScriptLoader.cpp#989
The disallow is called when we try to re-use the preloaded module load.
Comment 10•1 year ago
|
||
(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #9)
In our implementation, if the module load is of type preload, we won't disallow import-maps, otherwise import-maps won't work because we will preload modules.
OK I'm confused then. I thought that was the problem here (and this is the fix I was going to suggest).
Going back to the description of the problem:
so the module script will be preloaded before the import map is loaded
If we don't disallow import maps until the preload is used, why is there a problem? The module script preload should only get used after we have parsed the import map as far as I understand it.
Assignee | ||
Comment 11•1 year ago
|
||
(In reply to Jon Coppeard (:jonco) from comment #10)
OK I'm confused then. I thought that was the problem here (and this is the fix I was going to suggest).
Let me explain in more detail.
I guess you think the problem is:
- We preload the module
- We disallow the import-map
- import map is not loaded because it is disallowed.
- module script fails to resolve the specifier 'THREE'.
But it is not.
Because we actually don't do step 2 (disallow import-map when doing preload).
So the import map tag here is actually registered.
Is this what you think?
Going back to the description of the problem:
so the module script will be preloaded before the import map is loaded
If we don't disallow import maps until the preload is used, why is there a problem? The module script preload should only get used after we have parsed the import map as far as I understand it.
As mentioned above, we don't disallow import-maps in this case, as the (normal) module load happens after the import map is loaded.
What happened here are:
- Preload the module script (bug.js in this case)
- Parse the import map
- Load the external module script, bug.js. ScriptLoader found this is a preloaded request, so it reuses the preload request.
- Module script is fetched, then the module script is instantiated, but import-map is still being parsed, so it fails to resolve the specifier.
So the problem is the preloaded module script is used before the import-map is parsed.
It happens because the fetching happens before the import-map is parsed, and also the script is from a local server and its size is small,
so the fetching finishes very quickly.
Perhaps we could delay the preloaded module script or discard it and start a new load
But we don't know if the module script will actually use the specifier from the import-map
And it might hurt the performance for pages using import-maps.
Or we could preload the import-map as well (bug 1762595), but that brings some other problem as mentioned in comment 9.
We could also consider together with <modulepreload>, so let webpage itself decide whether to preload the module script or not.
Comment 12•1 year ago
|
||
(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #11)
Is this what you think?
That is what I thought originally.
What happened here are:
- Preload the module script (bug.js in this case)
- Parse the import map
- Load the external module script, bug.js. ScriptLoader found this is a preloaded request, so it reuses the preload request.
- Module script is fetched, then the module script is instantiated, but import-map is still being parsed, so it fails to resolve the specifier.
What I don't understand is that if we parse the import map in step 2, how is it still being parsed in step 4? Does this not all happen synchronously on the main thread?
Assignee | ||
Comment 13•1 year ago
|
||
(In reply to Jon Coppeard (:jonco) from comment #12)
What I don't understand is that if we parse the import map in step 2, how is it still being parsed in step 4? Does this not all happen synchronously on the main thread?
Sorry, I miss something, let me correct my comment 11.
- Preload the module script.
- the module is fetched, but fails to resolve the specifier so now it has parse error.
- Parse the import map.
- Load the external module script, and reuse the preloaded request.
- The preloaded request has parse error (from step 2), SM throws the error.
Comment 14•1 year ago
|
||
(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #13)
Aha, that explains it. Thanks.
Reporter | ||
Comment 15•1 year ago
|
||
(In reply to Yoshi Cheng-Hao Huang [:allstars.chh][:allstarschh] from comment #7)
Thanks for the clarification.
I'll duplicate this bug with Bug 1762595, as this problem should go away when we have speculative parsing of import-maps.
Many thanks for your help and the clear analysis.
Comment 16•1 year ago
|
||
Based on comment 9, I'm marking this as depending on bug 1762595 and setting priority and severity the same as that bug.
Assignee | ||
Updated•1 year ago
|
Comment 17•1 year ago
|
||
Is there a workaround for this? Can speculative parsing be disabled? It makes development very annoying; I have to reload on average 3 times before it's working.
I also don't understand S4 severity. This should affect everyone who is using import maps with a local development server.
Assignee | ||
Comment 18•1 year ago
|
||
I could check if this can be fixed without preloading the import-maps (bug 1762595), but this release will be freeze soon, so probably in the next release.
Comment 20•1 year ago
•
|
||
Hello, I reported bug 1833371, which may contain useful information.
I can confirm that this bug can occur on non-local web servers as I have observed it on a github page, here is the github issue that was open with us:
https://github.com/odoo/owl/issues/1436
and the state of the code at the time:
https://github.com/odoo/owl/blob/aa441274c7c588aeed504e1ee1ef19c44d411d20/docs/index.html
As noted in 1833371 the presence of other non-module scripts in the page before the import map seems to make the bug more likely. I don't know much about firefox internals but if I had to hazard a guess, it seems likely that it's because the non-module script is delaying the parsing of the import map.
I've created a fork of the above repo at that point in git history and enabled the github page, which showcases this issue happening on a web server: https://degueldre.dev/firefox-import-map-bug-demo/
Comment 21•1 year ago
|
||
https://bugdash.moz.tools/ is another site that exhibits this behaviour, although normally during a session restore; see issue 15 for some more details. I didn't hit this issue at all during development, locally or when fully hosted on Heroku.
I also don't understand S4 severity
I agree, S4 is defined as minor significance, cosmetic issues, low or no impact to users
.
This should be at least S3. S3 requires a work-around (Blocks non-critical functionality and a work around exists
). Technically rewriting your application to not use importmaps is a work-around, but not one that is always viable.
Will - would it be possible for you to consider retriaging this issue?
Assignee | ||
Comment 22•11 months ago
|
||
Comment 23•11 months ago
|
||
(In reply to :glob ✱ from comment #21)
https://bugdash.moz.tools/ is another site that exhibits this behaviour, although normally during a session restore; see issue 15 for some more details. I didn't hit this issue at all during development, locally or when fully hosted on Heroku.
I also don't understand S4 severity
I agree, S4 is defined as
minor significance, cosmetic issues, low or no impact to users
.This should be at least S3. S3 requires a work-around (
Blocks non-critical functionality and a work around exists
). Technically rewriting your application to not use importmaps is a work-around, but not one that is always viable.Will - would it be possible for you to consider retriaging this issue?
Updated•11 months ago
|
Comment 24•11 months ago
|
||
Comment 25•11 months ago
|
||
It would not be correct to remove modules that were already linked or evaluated.
Updated•11 months ago
|
Updated•11 months ago
|
Comment 26•11 months ago
|
||
Pushed by allstars.chh@gmail.com: https://hg.mozilla.org/integration/autoland/rev/3bc8c30ecc25 Don't use the preloaded module request if there's an import map. r=jonco https://hg.mozilla.org/integration/autoland/rev/bcbcbdf4f449 Add assertion that we only remove unlinked modules from the map r=allstarschh https://hg.mozilla.org/integration/autoland/rev/d6316cfb118d Add tests for the interaction between speculative preloading and module import maps r=allstarschh
Comment 27•11 months ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/3bc8c30ecc25
https://hg.mozilla.org/mozilla-central/rev/bcbcbdf4f449
https://hg.mozilla.org/mozilla-central/rev/d6316cfb118d
Comment 28•11 months ago
|
||
Backed out for causing top crash https://bugzilla.mozilla.org/show_bug.cgi?id=1835468 on nightly
Backout: https://hg.mozilla.org/mozilla-central/rev/c10ba3b6a8ecfaa3bebc0a33d8740e61594766c2
Comment 30•11 months ago
|
||
Copying crash signatures from duplicate bugs.
Comment 31•11 months ago
|
||
The bug is linked to a topcrash signature, which matches the following criteria:
- Top 10 desktop browser crashes on nightly
- Top 10 AArch64 and ARM crashes on nightly
:allstars.chh, could you consider increasing the severity of this top-crash bug?
For more information, please visit BugBot documentation.
Comment 34•10 months ago
|
||
Based on the topcrash criteria, the crash signature linked to this bug is not a topcrash signature anymore.
For more information, please visit BugBot documentation.
Updated•10 months ago
|
Updated•10 months ago
|
Updated•10 months ago
|
Assignee | ||
Comment 35•10 months ago
|
||
Move the test to mochitest-plain, as I'll use HTTP redirect to reproduce
the crash in later patch.
Assignee | ||
Comment 36•10 months ago
|
||
The crash of https://bugzilla.mozilla.org/show_bug.cgi?id=1835468 can be
reproduced by HTTP redirect in mochitest-plain.
When the script is being processed, sometimes the preloaded request is
still being loaded (for example, the script is being redirected to
another place). So we use the IsModulleFetched() check before calling
RemoveFetchedModule.
Comment 37•10 months ago
|
||
Pushed by allstars.chh@gmail.com: https://hg.mozilla.org/integration/autoland/rev/24f62f68f45a Part 1: Don't use the preloaded module request if there's an import map. r=jonco https://hg.mozilla.org/integration/autoland/rev/87fcd0af9ab0 Part 2: Add assertion that we only remove unlinked modules from the map r=allstarschh https://hg.mozilla.org/integration/autoland/rev/bf84446fdef4 Part 3: Add tests for the interaction between speculative preloading and module import maps r=allstarschh https://hg.mozilla.org/integration/autoland/rev/e0a7ff16a8ed Part 4: Move test to mochitest-plain test. r=jonco https://hg.mozilla.org/integration/autoland/rev/a1c94c7f0839 Part 5: Check IsModuleFetched() before removing it. r=jonco
Comment 38•10 months ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/24f62f68f45a
https://hg.mozilla.org/mozilla-central/rev/87fcd0af9ab0
https://hg.mozilla.org/mozilla-central/rev/bf84446fdef4
https://hg.mozilla.org/mozilla-central/rev/e0a7ff16a8ed
https://hg.mozilla.org/mozilla-central/rev/a1c94c7f0839
Updated•10 months ago
|
Description
•