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.
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.
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.
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.registerlater 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.
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.
Are you sure your race conditions aren't just the expected ordering ones?
There was a problem hiding this comment.
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.
Ok then it sounds like this top-out path is not working as it is supposed to.
There was a problem hiding this comment.
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.
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.
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.