Skip to content

Lazy controllers for user-land controllers #19

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

Merged
merged 1 commit into from
Feb 1, 2021

Conversation

weaverryan
Copy link
Member

@weaverryan weaverryan commented Jan 26, 2021

Hi!

This allows users to make their own controllers "lazy" by adding a special comment above their controllers:

// assets/controllers/hello_controller.js
import { Controller } from 'stimulus';

/* stimulusFetch: 'lazy' */
export default class extends Controller {
    // ...
}

When you do this, your controller (and its dependencies) are not included in the main app.js built file. Instead, they are split into their own chunk/file. This file is loaded asynchronously the moment that the first element appears on the page for this controller (e.g. <div data-controller="hello">). This follows up on #15 (and only the last commit is new to this PR). The /* stimulusFetch: 'lazy' */ is inspired by Webpack's /* webpackMode: 'lazy' */ comments and uses the same mechanism to parse them.

To activate this, you only need to process your controllers through a new loader:

// assets/bootstrap.js

export const app = startStimulusApp(require.context(
-    './controllers',
+    '@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
    true,
    /\.(j|t)sx?$/
));

That looks a bit ugly, but this is code that we'll give users via the recipe anyways. I've tested this in a real app and it works beautifully ❤️ .

Cheers!

@tgalopin
Copy link
Contributor

tgalopin commented Jan 26, 2021

People use a lot the 'use strict'; syntax to declare strictness. Would it make sense to have 'use lazy'; as a notation instead of a comment?

@weaverryan
Copy link
Member Author

I don’t know! I’ll admit that this is the weirdest part - I’m inventing something. However, comments can be removed in the final, minimized code, which is perfect because the comments are there only to hint to the compiler. So in some ways, it seems more appropriate (though in theory we could find and remove the “use lazy”). And also, I think it would be harder to parse for that string - the comments thing was easy.

If we feel strongly about the change, I can try it. But we do have a mechanism to deprecate the comment later if we don’t like it: we just parse for it in the loader and logger a deprecation. So it’s changeable.

@weaverryan weaverryan force-pushed the lazy-controller-loader branch 2 times, most recently from 594f06b to bec5610 Compare January 27, 2021 16:38
@tgalopin
Copy link
Contributor

After thinking about it I do agree the comment is the most suited option. I'm not sure how it would work with Typescript though: would it be removed by ts-loader before webpack can read it?

(+ needs rebase)

@weaverryan
Copy link
Member Author

I'm not sure how it would work with Typescript though: would it be removed by ts-loader before webpack can read it?

It appears to work fine with Typescript - even in a production/minified build. I expected this - since we're using the same mechanism that Webpack uses - but I just tried it locally on a project.

@weaverryan weaverryan force-pushed the lazy-controller-loader branch from bec5610 to 46c11d7 Compare February 1, 2021 15:09
@weaverryan weaverryan force-pushed the lazy-controller-loader branch from 46c11d7 to bbf8ab0 Compare February 1, 2021 15:54
@tgalopin
Copy link
Contributor

tgalopin commented Feb 1, 2021

Thanks Ryan.

@tgalopin tgalopin merged commit 0d8a3d7 into symfony:main Feb 1, 2021
@weaverryan weaverryan deleted the lazy-controller-loader branch February 1, 2021 17:58
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

Successfully merging this pull request may close these issues.

2 participants