JsCollectionOptimizerLazy tries to aggregate external files

Created on 21 February 2024, over 1 year ago
Updated 30 April 2024, over 1 year 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 18 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 over 1 year 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 over 1 year ago
  • πŸ‡¬πŸ‡§United Kingdom catch

    OK going to close this as cannot reproduce.

Production build 0.71.5 2024