-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto import and core refactoring #2216
Conversation
coreFile by file impact
extrasFile by file impactPull request have no impact on |
Released in 6.4.0. |
Thanks for implementing this refactor! 😊 I was able to do some more indepth tests and the basic functionality works. However, we have some race conditions. I'll point it out, in the code. |
systemJSPrototype.register = function (deps, declare) { | ||
if (hasDocument && document.readyState === 'loading' && typeof deps !== 'string') { | ||
var scripts = document.getElementsByTagName('script'); | ||
var lastScript = scripts[scripts.length - 1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, when using the condition document.readystate === 'loading'
, it is not guaranteed that the last script
of the page is indeed the one who called register()
. More specifically, this can happen when the first auto-imported script is calling a dynamic import (System.import()
) while there are still some script
tags being parsed in the page (either statically or dynamically)
I'll try to come up with a way to differentiate these dynamic imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh that makes sense. We should be able to specifically opt-out of SystemJS own-injected scripts from this mechanism somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this is very similar to the problem discussed below 🙈 , except that:
- the user is dynamically injecting a script using a regular dynamic load (
System.import
) during load, which will cause aSystem.register
later on ofc - the last script was not related to the System script, but another script at the end of the page
In other words, it doesn't seem such an edge case. 😊
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh weird, maybe that code path isn't working for some reason? I didn't fully test it yet - but yes that logic should be doing the avoidance here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure your race conditions aren't just the expected ordering ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, in my setup I have only one auto-imported script. In that script, there is a dynamic import to load the main chunk of the page. When System.register
of the chunk is being called, I can see it takes the src
of an unrelated script further down the page. So, in that sense, I don't expect any other ones. 😊
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok then it sounds like this top-out path is not working as it is supposed to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect the issue is that lastScript
is being checked in that dynamic import script, and not matching its own script as it is dynamic.
A timing-based fix with the registration system should be possible here... I will aim to take a look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, indeed. I don't think there is a full proof way in IE to distinguish System.register
's being called in the dynamic-import way vs the auto import way, as document.currentScript
cannot exactly be faked.
I see a couple of workarounds though, but they are never ideal:
- Disable auto-import once a first dynamic import is being called.
- Add a second condition next to
document.readyState === 'loading'
to check a specific attribute of thelastScript
. - Have dynamic imports only actually register (and not import) during the load phase of the element. This is a big change though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use the existing mechanism which is based on the sync timing of the register callback itself to register the script to the right URL. Integrating this with this code path will involve some timing tricks though and likely requires moving all this logic into an async step with checks.
This implements the auto import approach directly in core, as created by @tmsns in #2210, extending it to any number of scripts.
In addition this includes core refactoring to make processing phases more clear for import map and script processing.