Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load controllers from subdirectory #44

Open
devsigner-xyz opened this issue Jul 5, 2021 · 6 comments
Open

Load controllers from subdirectory #44

devsigner-xyz opened this issue Jul 5, 2021 · 6 comments

Comments

@devsigner-xyz
Copy link

devsigner-xyz commented Jul 5, 2021

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.

image

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:

image

@trsteel88
Copy link

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.

@kevinsaul
Copy link

@trsteel88 I have the same need, did you find the way ?

@pascalwacker
Copy link

pascalwacker commented Mar 10, 2022

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:');
  }
}

@thomas2411
Copy link

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.

@ThomasLandauer
Copy link

Thanks to @pascalwacker I found a way: https://stackoverflow.com/q/74448824/1668200

@thomas2411
Copy link

I have managed to load controllers from vendor directory thanks to @weaverryan like this:

import { startStimulusApp } from '@symfony/stimulus-bridge';
import { definitionsFromContext } from '@hotwired/stimulus-webpack-helpers';
// all the normal stuff


// 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,
    /\.[jt]sx?$/
));

app.load(definitionsFromContext(require.context(
    '@symfony/stimulus-bridge/lazy-controller-loader!../vendor/my/cms-bundle/Resources/assets/controllers',
    true,
    /\.[jt]sx?$/
)));

But as @devsigner-xyz mentioned I cannot find a solution to load controllers per context (different for admin and frontend)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants