Error when calling multiple bundle()->enqueue() on Sage 10

Hello guys !

I am encountering a small bug with setting up multiple bundle()->enqueue().

Basically, I’m trying to load a CSS file only when I need it through Composers or Components. It all works fine.

bundle('app')->enqueue();
bundle('blocks/hero-banner')->enqueue();

The problem is that I get lots of errors in the console when I load bundle() more than once.

Uncaught (in promise) DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "bud-activity-indicator" has already been used with this registry
    at new IndicatorController (http://localhost:3000/vendor/bud.app.blocks/hero-banner.blocks/lft-rgt.blocks/border.blocks/pusher.blocks/testimonial.blocks/hp-simulator.blocks/latest-articles.blocks/partner-slide.blocks/push-newsletter.blocks/push-map.testing.js:342:24)
    at http://localhost:3000/vendor/bud.app.blocks/hero-banner.blocks/lft-rgt.blocks/border.blocks/pusher.blocks/testimonial.blocks/hp-simulator.blocks/latest-articles.blocks/partner-slide.blocks/push-newsletter.blocks/push-map.testing.js:54:23

So, I lose the hot reload features because the script execution fails.

how to reproduce

In the setup.php file, add a new bundle call like this :

bundle('app')->enqueue();
bundle('testing')->enqueue();

bud.config.js

.entry({
  ...
  'testing': ['styles/blocks/testing.scss'],
});

Am I doing something wrong?

Thank :slight_smile:

I can reproduce this and can think of a couple things we could do on our end to improve our client script in order to prevent this.

That said, generally speaking, I think this is the wrong approach. There is meant to be a single entrypoint per page. An entrypoint isn’t a single script or module, it is the set of scripts or modules you need for a page to operate. So, you have a few ways you could go about improving this on your end, too.

You could use dynamic import statements to conditionally load scripts within the application. This is probably the best approach in that is the most optimal for your end users:

// do a search for 'dynamic import' on the discourse or 
// read the webpack docs for more info on how to set this up
(async() => {
  const conditionalScript = await import('./conditionally-needed-module.js')
  conditionalScript.doStuff()
})()

Alternatively, you could use a standard module architecture where you create a new entrypoint in the root of resources/scripts and import what you need:

// entry-a.js
import {a} from './components'

// entry-b.js
import {b} from './components'

// entry-c.js
import {a, b} from './components'

Then add the entrypoint to bud.config.js

    app.entry({
      ['page-a']: ['scripts/entry-a.js'],
      ['page-b']: ['scripts/entry-b.js'],
      ['page-c']: ['scripts/entry-c.js'],
    })

Lastly, you could use bud.config.js to define all scripts/styles needed for an entrypoint:

    app.entry({
      ['page-a']: ['scripts/entry-a.js'],
      ['page-b']: ['scripts/entry-b.js'],
      ['page-c']: ['scripts/entry-{a,b}.js'],
    })

That one is probably my least favorite.

In either of the last two examples, you just call bundle once in PHP, using an if statement or some similar control flow to specify which bundle is to be loaded on a particular page or set of pages. In the first example you don’t even need to touch php.

2 Likes

I have the same problem when adding multiple .entry in buds.config.js and enqueue it using Roots Bundle.

It shows an error in the inspect console when using yarn dev.

Uncaught (in promise) DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "bud-activity-indicator" has already been used with this registry
    at new IndicatorController (http://sage-boiler.lndo.site:40531/vendor/bud.app.front.blog.js:327:24)
    at http://sage-boiler.lndo.site:40531/vendor/bud.app.front.blog.js:48:23
bud.app.front.blog.js:1553

Here is my setup in buds.config.js

.entry({
      app: ['@scripts/app', '@styles/app'],
      front: ['@scripts/home'],
      blog: ['@scripts/blog'],
    })

Then in the setup.php

// buds styles & scripts
    bundle('app')->enqueue();

    if( is_front_page() ) {
        bundle('front')->enqueue();
    }

    if( is_home() ) {
        bundle('blog')->enqueue();
    }

This error only show when using yarn dev. But when I use yarn build, everything is working fine.

1 Like

This issue is fully fixed by 5.7.0, I believe. I still strongly advise against enqueuing multiple entrypoints per page.

1 Like