Problem/Motivation
The JsOptimizer class doesn't properly match the domain when preserving external JS, which can create issues that only occur on a live site. This requires explanation, listed below.
This applies to 8.x-4.x and 8.x-3.x, and potentially previous branches as well.
The scenario:
Imagine you have an external JavaScript named like so:
https://cdn.example.com/js/www.mysite.com/myfile.js
This is added as an external JavaScript to the website "www.mysite.com".
On the live site, you observe the following error when AdvAgg aggregates JS:
Warning: file_get_contents(513640/mmapi.js): failed to open stream: No such file or directory in Drupal\Core\Asset\JsOptimizer->optimize() (line 25 of /mnt/www/html/mysite01live/docroot/core/lib/Drupal/Core/Asset/JsOptimizer.php)
You also observe that there is a JavaScript whose entire contents is a single semi-colon:
;
The cause:
The cause for this behavior appears to be around line 46 in src/Asset/JsOptimizer.php. Here you will see this:
if ($asset['type'] === 'external') {
// If type is external but path doesn't start with http, https, or //
// change it to file.
if (stripos($path, 'http') !== 0 && stripos($path, '//') !== 0) {
$asset['type'] = 'file';
}
// If type is external and starts with http, https, or // but points to
// this host change to file, but move it to the top of the aggregation
// stack as long as js.preserve_external is not set.
elseif (stripos($path, $this->basePath) !== FALSE && !$this->config->get('js.preserve_external')) {
$asset['type'] = 'file';
$asset['group'] = JS_LIBRARY;
$asset['every_page'] = TRUE;
$asset['weight'] = -40000;
$asset['data'] = substr($asset['data'], stripos($asset['data'], $this->basePath) + $this->basePathLen);
}
}
Notice this specific part:
stripos($path, $this->basePath) !== FALSE
This condition will match, causing the JS being loaded to change from loading over HTTP to loading via local filesystem.
Proposed resolution
Change the "stripos" line to check for the domain match instead of simply whether the current domain exists in the external JS URL.
Remaining tasks
Create a patch / MR.