Problem/Motivation
modules/charts_chartjs/charts_chartjs.libraries.yml (5.1.x and 5.2.x) defines:
chartjs: version: 1.x js: js/charts_chartjs.js: { weight: -1, attributes: { defer: true } } dependencies: - charts/global - charts_chartjs/chartjs
Drupal's AssetResolver::getJsAssets() sorts JavaScript by weight and only preserves dependency order between files of equal weight (it adds a tiny insertion-order fraction to the weight). Because js/charts_chartjs.js has an explicit weight: -1 while charts/global (js/charts.js) keeps the default weight 0, charts_chartjs.js is emitted before charts.js, i.e. before its own dependency. Measured on Drupal 11.4 with charts 5.2.2:
modules/contrib/charts/modules/charts_chartjs/js/charts_chartjs.js weight=-0.9997 modules/contrib/charts/js/charts.js weight= 0.00013
On a plain page load this is masked: charts_chartjs.js is defer and charts.js is not, so charts.js still executes first. But when the chart sits inside a BigPipe placeholder (e.g. a Views chart block placed with Layout Builder, or any block with a lazy builder) or arrives in an AJAX response, both files are added dynamically by loadjs in document order and defer no longer applies. charts_chartjs.js then executes first and registers Drupal.behaviors.chartsChartjs. If any Drupal.attachBehaviors() runs between the execution of the two files (another BigPipe placeholder being replaced does exactly that), the behavior runs while Drupal.Charts does not exist yet:
Uncaught TypeError: Cannot read properties of undefined (reading 'Contents') at Object.attach (modules/contrib/charts/modules/charts_chartjs/js/charts_chartjs.js:21) at Drupal.attachBehaviors (core/misc/drupal.js:162) at core/modules/big_pipe/js/big_pipe.js:137
The new Drupal.Charts.Contents() call sits before the once() guard, so the error is thrown even when there is nothing for that attach round to do. The error is intermittent (it depends on the order in which placeholders arrive) and the chart usually still renders on a later attach round, so the visible symptom is "random console errors on chart pages".
Steps to reproduce
- Drupal 10.3+/11 with BigPipe enabled, charts + charts_chartjs 5.2.x.
- Place a Views chart block (Chart.js) on a page via Layout Builder together with at least one other block that is BigPipe-placeholdered (anything with a
#lazy_builder, e.g. a per-user block). Log in so BigPipe streams. - Load the page a few times with the console open: intermittently the TypeError above appears. Confirm the asset order with
\Drupal::service('asset.resolver')->getJsAssets()for the librariescharts/globalandcharts_chartjs/chartjs.
Proposed resolution
Remove the explicit weight so the file simply follows its dependency:
js/charts_chartjs.js: { attributes: { defer: true } }
Alternatively, if the -1 is intentional (to run before other libraries at weight 0), give charts/global's js/charts.js a lower weight (e.g. -2) so it still precedes every backend script. Either way Drupal.Charts is then guaranteed to exist when chartsChartjs.attach runs.
Optionally harden charts_chartjs.js as well: move new Drupal.Charts.Contents() inside the once() loop, or bail out early if Drupal.Charts is undefined, so a stray early attach round cannot throw.
Workaround for sites
/** * Implements hook_library_info_alter(). */ function MYMODULE_library_info_alter(array &$libraries, $extension): void { if ($extension === 'charts_chartjs' && isset($libraries['chartjs']['js']['js/charts_chartjs.js']['weight'])) { unset($libraries['chartjs']['js']['js/charts_chartjs.js']['weight']); } }
Verified on our site: with the weight removed the order becomes charts.js (0.00013) before charts_chartjs.js (0.0003) and the error no longer occurs on pages with 7–9 BigPipe-loaded charts.
Remaining tasks
Review the MR (one-line change in charts_chartjs.libraries.yml).
Issue fork charts-3620588
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:
- 3620588-oneline
changes, plain diff MR !232
- 3620588-charts-chartjs-weight
changes, plain diff MR !231
Comments
Comment #3
magnolia61 commentedMR !231 opened against 5.2.x: https://git.drupalcode.org/project/charts/-/merge_requests/231
One-line change: drop the explicit
weight: -1fromjs/charts_chartjs.jsincharts_chartjs.libraries.ymlso it follows its dependencycharts/global. Measured order after the change:charts.js0.00013 beforecharts_chartjs.js0.0003; thereading 'Contents'TypeError no longer occurs on our BigPipe pages with 7–9 charts.Comment #8
andileco commentedThanks for your contribution, @magnolia61. Your MR had a lot of extra code, so I just took your one line and made a new MR.