JsCollectionOptimizerLazy tries to aggregate external files

Created on 21 February 2024, about 1 year ago
Updated 30 April 2024, 12 months ago

Problem/Motivation

Given a library with

something:
  js:
    https://example.com/external.js: { type: external }

Using code similar to:

    $assets = new AttachedAssets();
    $assets->setLibraries($attachments['library'] ?? [])
      ->setAlreadyLoadedLibraries([])
      ->setSettings($attachments['drupalSettings'] ?? []);
    $css_assets = $this->assetResolver->getCssAssets($assets, $optimize_css);
    [$js_assets_header, $js_assets_footer] = $this->assetResolver->getJsAssets($assets, $optimize_js);

JsCollectionOptimizerLazy will try to do a file_get_contents() on the remote URL.

The above will give us 2 attachments in js_assets_footer, one is the external library, the other is the aggregated JS like:

https://example.com/sites/default/files/js/js_sZ03LyFKf2Dn_Gf7OqpmIhNnWA.......(big string)

However when visiting that URL, Drupal returns:

/* @license GNU-GPL-2.0-or-later https://www.drupal.org/licensing/faq */
;

For some reason the optimized JS is completely empty.

Oddly enough, if you change `delta` in that URL to something else, it will return what I expect. My theory is that it's returning the wrong delta back.

I was able to temporarily fix the issue by either:
1. Removing the external library
2. Turning off JS aggregation
3. Overridding services:

  # @todo: These are the deprecated (but working) collection optimizers.
  asset.css.collection_optimizer:
    class: Drupal\Core\Asset\CssCollectionOptimizer
    arguments: [ '@asset.css.collection_grouper', '@asset.css.optimizer', '@asset.css.dumper', '@state', '@file_system']
  asset.js.collection_optimizer:
    class: Drupal\Core\Asset\JsCollectionOptimizer
    arguments: [ '@asset.js.collection_grouper', '@asset.js.optimizer', '@asset.js.dumper', '@state', '@file_system']

Steps to reproduce

Reproducible with above code, working on PoC.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Closed: cannot reproduce

Version

11.0 πŸ”₯

Component
Asset libraryΒ  β†’

Last updated 2 days ago

No maintainer
Created by

πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @djdevin
  • πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia
  • πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia

    Possibly the same as πŸ“Œ Asset optimization breaks functionality Active

  • πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia
  • πŸ‡¬πŸ‡§United Kingdom catch

    Had a look at the logic. I think the problem might be that preprocess is set to TRUE by default, and it's not set to false for external files automatically.

    You could try explicitly setting preprocess: false in the library definition - or this MR might work, but I haven't tested it, just a theory.

  • Status changed to Needs work 12 months ago
  • πŸ‡¬πŸ‡§United Kingdom catch
  • πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia

    I tried the MR and those suggestions to no avail. I noticed the problem was no longer happening for me so I backtracked over any changes and found out that I added a dependency on a completely different library, to a completely different library (on core/once) which causes some change in how the JS gets grouped.

    As a test, I just added a dependency on core/once to the broken external library (which has no dependencies) and that also worked.

    some-external-library:
      js:
        //domain.com/ext.js: { type: external, minified: true }
        //domain.com/ext2.js: { type: external, minified: true }
      dependencies:
        # Why is this needed? We don't know.
        - core/once
    

    Can't figure it out but at least I know removing that seemingly innocuous library dependency triggers the issue.

    The working JS output looks like:

    When the JS is broken it looks like: with that last aggregated file being blank. Regular pages are unaffected, only broken in this case where we are calling getJsAssets() manually for some decoupled functionality.
  • πŸ‡ΊπŸ‡ΈUnited States djdevin Philadelphia

    It's me, hi, I'm the problem, it's me...

    We had this code altering JS, removing it also fixes the issue.

    function xxx_js_alter(&$javascript, AttachedAssetsInterface $assets) {
      $request = \Drupal::request();
      if ($request->getPathInfo() === '/xxx') {
        unset($javascript['core/misc/drupal.init.js']);
        unset($javascript['core/misc/drupalSettingsLoader.js']);
        unset($javascript['core/misc/drupal.js']);
      }
    }
    

    Though I'm not sure why doing that wiped out the rest of the JS, and how adding a dependency on core/once fixes it.

  • Status changed to Closed: cannot reproduce 12 months ago
  • πŸ‡¬πŸ‡§United Kingdom catch

    OK going to close this as cannot reproduce.

Production build 0.71.5 2024