stimulus-bridge
stimulus-bridge copied to clipboard
Load controllers from subdirectory
Hello, I am trying to figure out how can I create multiple bootstrap.js files and load controllers from subdirectories, the purpose of this is load only the required JS per context instead of loading all controllers everywhere. I have the feeling that I am missing something but I tried a lot of things and I can't get it to work. Example:
Originally I have bootstrap.js with this content:
import { startStimulusApp } from '@symfony/stimulus-bridge';
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
export const app = startStimulusApp(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
true,
/\.(j|t)sx?$/,
));
This is great, I import bootstrap.js in my entrypoints and I can use stimulus controllers everywhere, but this cause that a lots of unused JS appear in differente bundles, as you can see in the image below, mixitup and intlTelInput should not be there since I used both packages in other context but not in this one.

What I want to do is create bootstrap.js files per context to minimize this unused JS but I can't get to work controllers in subdirectories with stimulus-bridge.
// bootstrap_landing.js
import { startStimulusApp } from '@symfony/stimulus-bridge';
export const app = startStimulusApp(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers/landing',
true,
/\.(j|t)sx?$/,
));
//landing.js Encore entrypoint
import '../../bootstrap_landing';
// other landing stuff
// bootstrap_extranet.js
import { startStimulusApp } from '@symfony/stimulus-bridge';
export const app = startStimulusApp(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers/extranet',
true,
/\.(j|t)sx?$/,
));
// extranet.js Encore entrypoint
import '../../bootstrap_extranet';
// other extranet stuff
By doing this, the final bundle that I have show before should be something like this:

I would like to know how to do this as well. My objective is to have the following structure:
- assets/global/controllers
- assets/frontend/controllers
- assets/admin/controllers
Global controllers would be loaded in both frontend and admin. At the moment the only way I can see to create duplicate files within admin/frontend controllers which just import and then export the var from global.
@trsteel88 I have the same need, did you find the way ?
Same here, I've tried it with
export const app = startStimulusApp(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
true,
/\.(j|t)sx?$/
));
app.load(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!../general/controllers',
true,
/\.(j|t)sx?$/
));
However, this doesn't register the controllers in the ../general/controllers folder, but instead I get an Uncaught TypeError: constructor is undefined thrown along the stack.
Did anyone find a proper solution for this? My workaround is to create "dummy" controllers... Ex.
// frontend/controllers/foo_controller.js
import Foo_controller from "../../general/controllers/foo_controller";
export default class extends Foo_controller {
}
// general/controllers/foo_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
console.log('this seams like a really stupid workaround :shrug:');
}
}
I have the same problem. I would like to load controllers from multiple directories on both assets/controllers as well as vendor/mybundle/Resources/assets/controllers.
Thanks to @pascalwacker I found a way: https://stackoverflow.com/q/74448824/1668200