Problem/Motivation
Following the #3113400: Deprecate more jQuery UI library definitions update, this was discovered as the order of jQuery UI assets could change depending on whether there is a sufficiently large library loaded between two jQuery UI dependent libraries, which exposed an underlying problem with how asset weights are interpreted.
The bug is a side-effect of using non-integer weights for assets in jQuery UI libraries.
In particular, this AssetResolver::getJsAssets()
logic:
$options['weight'] += count($javascript) / 1000;
Based on @jmickela's findings:
The javascript array is an array of files currently staged to be included, and grows by one with every iteration though the array of libraries. If all the weights were integers this wouldn't have an impact on the loading order, but the weights in the jQuery UI library use decimals now.
If two files are processed far enough apart from each other in the array, but have weights very close to each other, this change is enough to change the order they get loaded.
Widget's weight starts at -11.8, and Controlgroup at -11.7, if there's exactly 100 files in the array between them then they'll end up with the same weight, if there's 101 files then Controlgroup will get loaded before widget. I just checked an on the page I was testing on, I'm getting around 200 individual files.
Note that while this issue was discovered with JS assets, it also occurs with CSS assets, and the test coverage in this issue demonstrates that.
Steps to reproduce
Use a render array similar to:
[
'#attached' => [
'library' => [
'core/drupal.dialog',
// This library contains at least 100 javascript entries.
'jqueryui_library_assets_test/many-dependencies',
'core/drupal.autocomplete',
],
],
];
Proposed resolution
TBD.
would the recommended resolution be to change the fractional part of the weights from tenths to thousandths so that it's much less likely to run into the bug?
The alternative is to try and revisit the AssetResolver
logic and see if it can be made more deterministic without introducing its own subtle bugs e.g. changing the divisor from 1000
to 3000
or higher.
Remaining tasks
Provide an issue fork/patch.
User interface changes
None
API changes
TBD
Release notes snippet
TBD
Workaround:
Disable JavaScript aggregation at /admin/config/development/performance
Comment | File | Size | Author |
---|---|---|---|
#80 | 3222107-80.patch | 1.31 KB | Spokje |
#72 | 3222107_95x.patch | 24.02 KB | bnjmnm |
#72 | test-only-js-95x.patch | 24.09 KB | bnjmnm |
#72 | test-only-css-95x.patch | 24.15 KB | bnjmnm |
#60 | interdiff_54-60.txt | 7.47 KB | bnjmnm |
Issue fork drupal-3222107
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
codebymikey CreditAttribution: codebymikey at Zodiac Media commentedAttached a copy of a test-only patch to demonstrate the breaking change.
Comment #3
nod_Nice find
Comment #4
codebymikey CreditAttribution: codebymikey at Zodiac Media commentedAttach a patch addressing a minor typo breaking the test.
Comment #5
codebymikey CreditAttribution: codebymikey at Zodiac Media commentedComment #6
codebymikey CreditAttribution: codebymikey at Zodiac Media commentedUploading a proposed fix by @jmickela in here to see if it passes the default Drupal tests.
Comment #8
jmickelaAfter thinking about it a bit, if non-integer weights are allowed I then I feel like changing the divisor to 3000 really isn't enough, this patch changes it to 30,000 instead. With this you'll need to load 3,000 JS files before the chance of a loading order issue comes up; assuming the weights used are tenths. If it's valid to use weights like -10.00001 then this approach is fundamentally flawed.
I think the real fix is to only allow integer weights and possibly increasing the divisor value as well. As it is, even with integer weights you can run into this problem if you're loading over 1,000 JS files. If it would work just as well to use something like 30,000 as the divisor, then I don't think there's a reason not to, that would make it very unlikely to run into this issue as I would imagine a site using 30,000 JS files would probably run into other issues.
Comment #9
nod_can we get a patch with both the tests and the code change? because there is no guarantee this is fixed by the code :)
The "real" fix is #1945262: Replace custom weights with dependencies in library declarations; introduce "before" and "after" for conditional ordering where weights are not even a thing anymore.
In the meantime I think this is a good enough fix.
Comment #11
codebymikey CreditAttribution: codebymikey at Zodiac Media commentedAttached a patch with @jmickela's fix along with the test.
Comment #12
bnjmnmMentioned in the MR, but I think this is pretty close to RTBC, but I'd like the test coverage for this to not be dependent on jQuery UI since that has an expiration date likely happening before this fix is no longer needed. To be safe, there should probably be a new test-only patch with the refactored tests, while the MR can be the tests+fix.
Feel free to ping me on Drupal Slack when the test is refactored and I'll re-review, I'll be happy to see this one land.
Comment #13
larowlanWhen we get to D10, and drop IE support, can we solve this with ES module imports and let the browser sort it out 😈?
Comment #15
dtarc CreditAttribution: dtarc at Affinity Bridge commentedPatch in #11 worked for us.
Comment #16
maxilein CreditAttribution: maxilein commentedI'd divide by 7000 instead of 3000.
Comment #17
SocialNicheGuru CreditAttribution: SocialNicheGuru commentedPatch in #11 worked for me too
Comment #18
catchComment #20
trickfun CreditAttribution: trickfun commentedPatch doesn't works for me if bigpipe is enable.
drupal 9.3.14
Comment #21
maxilein CreditAttribution: maxilein commentedI have bigpipe enabled and it works just fine.
Why do you think it is connected with bigpipe?
Comment #22
trickfun CreditAttribution: trickfun commentedI have errors only when bigpipe is enabled.
The error occurred on all pages.
Comment #23
Alina Basarabeanu CreditAttribution: Alina Basarabeanu at Cyber-Duck commentedPatch #11 works on drupal/core (9.4.2)
Comment #24
SamLerner CreditAttribution: SamLerner at CivicActions for Centers for Medicare and Medicaid Services commentedI can confirm that the .diff in #11 is working for me on Drupal 9.4.3
Comment #25
Wim LeersMarked #3272295: JavaScript errors in admin when using autocomplete and CKEditor 5 as a duplicate of this, thanks @nod_ for pointing me here!
Comment #26
Nowrie CreditAttribution: Nowrie commentedPatch #11 also works on drupal/core (9.4.6)!
Comment #28
steveoriolPatch #11
works also well on D9.4.8The patch applies well, but after some tests, some js and css files are not loaded anymore (found) and blocks some pages of the website.
Comment #29
SamLerner CreditAttribution: SamLerner at CivicActions for Centers for Medicare and Medicaid Services commentedIt sounds like the patch is consistently working. However, the merge request needs rebasing before it can be merged: https://git.drupalcode.org/project/drupal/-/merge_requests/954#note_34300
If we could get that done, I feel like this would be RTBC.
Comment #30
steveoriolbad news for me, in fact even if the patch applies well to the core of Drupal 9.4.8,
I have some js and css files that are no longer loaded (found) and that block pages of the site.
And by removing the patch it works again...
[...]
I need the patch to use it with the new ckeditor 5 module for D9.
I tested the patch in version #8
For the moment it seems to work without any inconvenience.
Comment #31
Shubham Chandra CreditAttribution: Shubham Chandra as a volunteer and at Dotsquares Ltd. commentedRe-rolled patch #11 in drupal 10.1.x
Comment #32
quotientix CreditAttribution: quotientix commented#8 is working fine. Thanks for the patch!
Comment #36
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Webform module Open Collective, The Big Blue House commentedThe latest dev release of the Webform module is running into this issue via translations.
@see #3329097: Issues with CKEditor 5, tokens, translations
The patch works as expected but I'm not seeing any immediate workarounds
Comment #37
super_romeo CreditAttribution: super_romeo as a volunteer commentedMerge request !954
on D9.5.1 works.Comment #38
Chi CreditAttribution: Chi commentedAttaching media is completely broken in Umami profile when JS aggregation is enabled.
I think this can be considered as major issue.
Comment #39
redseujacjrockowitz wrote in #36:
The issue with CKEditor vs CSS/JS aggregation is NOT fixed in the most recent 6.2.x-dev version.
Notice this issue has nothing to do with translations, but with incompatibility of CKeditor and CSS/JS aggregation. If aggregation is disabled, you can write text in the textboxes with CKeditor, otherwise you cannot, because there are JS errors blocking CKEditor from working as expected.
For the errors see #20 @: #3329097: Issues with CKEditor 5, tokens, translations
This seems a major issue.
Comment #40
maxilein CreditAttribution: maxilein commentedIt is a major issue. But the symtoms can differ from site to site depending on which css or js files you load... also in which order they are loaded.
Having said that: they can cause ALL kinds off issues!
The difficulty of diagnising this as the problem for any random js or css issue makes it a major issue in my opinion.
Since it is hard to get from a strange error to this issue ...
As a workaround until this is fixed: I am using #11 but I am dividing by 7000. Rarely had an issue.
Comment #41
bnjmnmThe offer in #12 (and the MR comment above it) still stands. Move the tests to not depend on jQuery UI assets, and it's ready for RTBC. Making that requested change will also address the test that is failing on the more recent patches/MRs. That's one of the scenarios I wanted to prevent with that request.
Here's what I said further up and it still stands:
Just refactor that test and I think this is good to go.
Comment #42
maxilein CreditAttribution: maxilein commentedI agree. to #41
This is not jQuery specific.
Comment #43
AnybodyJust ran into this with layout_paragraphs on Drupal 9.5.3. Shouldn't we mark this "Critical"?
Comment #44
AnybodyAdded
to the issue summary.
Comment #45
gwenweb CreditAttribution: gwenweb at WebstanZ commented#31 worked fine for me. Thanks !
Found this issue after having seen this kind of errors in the backoffice page console :
with a website using advagg, entity_browser and field_group
Comment #46
maxilein CreditAttribution: maxilein commentedMaybe we should rename this issue in order to make it more easily findable for people.
e.g.
"Large number of javascript files may cause multiple random script errors due to loading order of js files"
Comment #47
benJBmC CreditAttribution: benJBmC commentedThe patch #31 works for me too, thanks! I had an error using the ebt_slick_slider module when adding media to the custom block:
Uncaught TypeError: $element.dialog is not a function
Comment #48
AnybodyWe're running into this issue on several projects again and again in the last weeks with different results / error messages. I'm wondering why this didn't pop up earlier? Have there been related changes in recent core releases?
At the current state, I think it's important to find a solution here, should we perhaps increase the priority to critical?
In #10 @larowlan wrote
Is that possible? Then we could at least look forward to a solution in 10.1.x (and should target that?!)
Comment #49
agoradesign CreditAttribution: agoradesign commentedpatch #31 works for us as well - had problems on taxonomy term edit pages after switching to ckeditor5
Comment #50
czigor CreditAttribution: czigor commentedOn my node form I have a CKeditor textarea field, a plain file field and a media field with media library widget.
Due to the broken js the files uploaded to the plain file field are not set to permanent which causes them to be deleted after 6 hours.
Comment #51
FiNeX CreditAttribution: FiNeX as a volunteer commentedHi, patch #31 works on my case: before the patch non admin users were not able to open the media library widget and other dialogs (when ckeditor5 was enabled). Thank you.
Comment #52
catchBoth the patch in #31 and the MR are failing tests. The next step here would be to try to fix that test failure. Agreed this should be critical.
Comment #53
catchThe MR needs to be re-done against 10.1.x and we need to use something other than jQuery UI to test it.
Comment #54
bnjmnmCreated tests that aren't dependent on jQuery UI. Those tests also exposed that the same problem exists with CSS, so a fix was provided for that as well.
Comment #57
bnjmnmUpdated IS to make it clear jQuery UI was where it was discovered, but the issue is not specific to it.
Comment #58
smustgrave CreditAttribution: smustgrave at Mobomo commentedI need to give complete kudos for the tests.
#54 shows this covers the problem for js/css
So the actual change looks good to me and matches the proposed solution from the summary.
Comment #59
larowlanIt pains me to put this back to needs work on the tests only, because its a long-standing critical - but I think we can improve the test in a few ways, and at least one of those changes (asserting a count) feels blocking
If we're touching this, could we add a docblock here (if not can be fixed on commit)
Library entries support attributes, would it be simpler to add a data-weight attribute in the definitions and then we can use
findAll('css', 'script[data-weight]')
and similar for links.So that would remove the need for:
* the array_filter
* the explode, str_contains, substr, strpos
I think it would make the test easier to read/understand.
Let's assert the count of files here, if both are empty, this will still pass (Same for the css).
We can probably use
::assertGreaterThan(0, count($js_files))
So its not a hard-coded number that is subject to fluctuation and therefore more expensive to maintain.
Comment #60
bnjmnmAddresses all the points in #59, great suggestions.
Comment #61
smustgrave CreditAttribution: smustgrave at Mobomo commentedReviewing the interdiff and looks as all points have addressed from #59
Neat trick with the data-weight.
Comment #62
larowlanUpdated issue credits
Comment #64
larowlanCommitted to 10.1.x
Moving back to 10.0.x for backport once we have a green test-run.
Comment #65
larowlanBackported in 10.0.x, needs re-work for 9.5.x because of the .es6.js files 😭 - going to be a lot of them, all empty
Comment #67
Wim LeersSo was the actual root cause for the problem the division by 1000? i.e. that there was not enough precision?
In any case: superb work, @bnjmnm! 👏 Plus, this helps make #1945262: Replace custom weights with dependencies in library declarations; introduce "before" and "after" for conditional ordering more feasible, by having better test coverage for our decades old weight-based system before we transition to something better! 🥳
Comment #68
Wiktor7 CreditAttribution: Wiktor7 commentedHello, this works in my case.
Comment #69
catchMoving to needs work so it's clearer the patch needs a re-roll, vs. just a delayed cherry-pick.
Comment #70
Wim LeersNote that per #3357678: The block editor menu havent the "editor" (see #19 + #20 + #21) that this is causing CKEditor 5 to fail to load correctly in certain contexts too. This issue fixed it. It first shipped in a release in 10.0.9.
… but it's not yet fixed in 9.5.x. So this would appear to still be quite important to backport.
Caveat: I have not verified if this problem occurred in 9.5.
Comment #71
agoradesign CreditAttribution: agoradesign commentedI have encountered this problem on any 9.5.x site I've enabled CKE5 without this patch so far - but only on editing a taxonomy term
Comment #72
bnjmnm9.5.x reroll
Comment #75
redseujacWim Leers commented in #70:
I'm working with 10.0.9 and I'm glad to tell that my problems with Webforms/CKEditor5 are solved now. Before it was impossible to write/edit text in some textboxes managed by CKEditor5 there.
Comment #76
smustgrave CreditAttribution: smustgrave at Mobomo commentedReroll for 9.5 looks good.
Comment #78
catchCommitted/pushed the backport to 9.5.x, thanks!
Comment #79
SpokjeBackport breaks HEAD of
9.5.x
on PHP 7.3 (https://dispatcher.drupalci.org/job/drupal8_core_regression_tests/82519/...)_If_ we decide to not rollback and do a 'hotfix', let's see if attached patch works.
Comment #80
SpokjeRight..., measure twice, code once.
There are _two_ arrow syntax functions in the test.
Let's try this again...
Comment #81
SpokjeComment #83
catchWhoops. Committed/pushed to 9.5.x, thanks!
Comment #84
MaxMendez CreditAttribution: MaxMendez commentedI'm using 9.5.9 and the problems seems to be solved for the admin user (user 1), but the problems seems to persist on user with low level of permissions.
Comment #85
MaxMendez CreditAttribution: MaxMendez commentedSorry, my mistake, it is fixed but has been released core versión with this patch.
Comment #86
jonurace CreditAttribution: jonurace commented#67 works for me- Thanks!!!
Comment #87
mr.pomelov CreditAttribution: mr.pomelov as a volunteer commented#72 work for me (Drupal 9.5.9, MySQL 5.7.30, PHP 8.1.7)
Comment #88
AnybodyConfirming this works fine! Very much looking forward to the next 9.5 patch release with this fix!
Comment #89
Wim LeersYay!
Updating title.
Comment #91
maxilein CreditAttribution: maxilein commentedThe issue is back with D10.1.
Since the other issue was postponed to D11.x, can we please make a patch for D10.1.
Comment #92
Martijn de WitIt was already in 10.1 right? see https://www.drupal.org/project/drupal/issues/3222107#comment-15007055
Comment #93
larowlanIt's all the way back to 9.5
Comment #94
maxilein CreditAttribution: maxilein commentedThanks. You are right. Forgive me! Same symptoms ... I'll investigate...
Comment #95
maxilein CreditAttribution: maxilein commentedIt seems that https://www.drupal.org/project/simple_popup_views was this issue.
It behaved very much randomly like problems caused by this issue. All kinds of javascript file errors, without any logical source that varied completely from the number of installed and uninstalled modules. So I post it here. It may help someone.
Comment #96
maxilein CreditAttribution: maxilein commentedIt turned out that it was just a coincidence of multiple contrib modules which did forget to migrate core/jquery to contrib before the upgrade to 10.1 and some missing dependencies in this context. Sorry and thank you.
Comment #97
gwvoigtDoes it work with 9.5.10? None of the patches apply to 9.5.10
Comment #98
ivnish CreditAttribution: ivnish commentedAlready committed to 9.5, see #77
Comment #99
gwvoigtThank you! I'm on 9.5.10 and still having issues when aggregation is on. In random instances the ckeditor don't load properly.
Comment #100
cecrs CreditAttribution: cecrs commented@gwvoigt
Check out this issue: https://www.drupal.org/project/drupal/issues/3370930
We were also still seeing problems with missing ckeditor5 toolbars, and it was caused by aggregate files not getting written to disk due to mismatched hashes. There isn't a patch for < D10, but it's minimal changes and easy to generate a patch for if you aren't on D10 yet. Appears to have resolved our issues.
Comment #101
maxilein CreditAttribution: maxilein commentedIs it possible that this also affects css at a simliar functionality?
When I aggregate css files not all styles are used.