Skip to content

"fetch: lazy": don't download until the controller is present #15

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 22, 2021

Hi!

This deprecates the webpackMode option in controllers.json and replaces it with a new lazy option that can be set to eager or lazy.

The lazy mode is quite a bit smarter than the old webpackMode: 'lazy'. When you use this, the controller (and its dependencies) isn't downloaded until the corresponding data-controller appears on the page. This is great for things like chartjs, which is quite huge, but probably you don't have it on every page and a tiny delay is no problem.

PR to update the UX packages: symfony/ux#53

Cheers!

Fixes #3

Copy link
Contributor

@tgalopin tgalopin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing! I love that this feature will be available!

@tgalopin
Copy link
Contributor

Could you rebase?

@weaverryan weaverryan changed the title lazy-controller mode: don't download until the controller is present [WIP] lazy-controller mode: don't download until the controller is present Jan 25, 2021
});
}
}
}))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this runs after babel, we need to rewrite this into "old" JavaScript to support all browsers. I have the code locally, just need to put it in here :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe we can make this run before babel

Copy link
Member Author

@weaverryan weaverryan Jan 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be nice... I just could not find a way to do that :/. We effectively would need to change the "filename" of the output source to something that ends in .js and get Webpack to, sort of, "restart" the process so that the normal .js loader can match it. That may be possible, but I couldn't find away. And... really, we ship "dist" code normally that has been pre-compiled with Babel. This just a special case of doing the same (the strangeness being that I'll rewrite this to ES5 manually).

@weaverryan weaverryan changed the title [WIP] lazy-controller mode: don't download until the controller is present lazy-controller mode: don't download until the controller is present Jan 25, 2021
* @param {Number} indentationSpaces Amount each line should be indented
*/

module.exports = function generateLazyController(controllerPath, indentationSpaces) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we have dist files committed in this repo ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should clean this up. Some dist files are needed because they're read at runtime in the browser - specifically the src/index.js file (which the user imports directly from their code and uses. But other things - like these loaders - are only executed at build time and do not need a dist.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even for the necessary ones, I don't think they need to be committed, as the npm ecosystem relies on a separate publishing step and so the VCS content and the package content can be different.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right about that too. None of them should be committed. However, we would need to make sure there was a more sophisticated build+publish functionality. The dist files are also committed in symfony/ux for the same reason: ease of distribution (because there is no automated build/release procedure).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

symfony/ux packages are not distributed through npm but through composer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

npm already has a built-in automation: it will run the prepublishOnly script before building the archive for publication.
you only need to update the package.json to make that prepublishOnly script run npm run build and that's automated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repo could definitely not include the dist files at all indeed. I added them without too much thoughts after having added them in symfony/ux.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's fix that in another PR

@weaverryan weaverryan changed the title lazy-controller mode: don't download until the controller is present "fetch: lazy": don't download until the controller is present Jan 27, 2021
@weaverryan weaverryan force-pushed the lazy-controllers branch 2 times, most recently from 510db70 to 1007648 Compare January 27, 2021 15:53
weaverryan added a commit to weaverryan/ux that referenced this pull request Jan 27, 2021
@weaverryan
Copy link
Member Author

I've updated the PR to use a fetch option that allows eager or lazy. The old webpackMode is still accepted, but it is ignored (and triggers a deprecation warning to guide users). We're still experimental, so we don't need to do this - but it was a simple thing to help guide users.

in `controllers.json` to `lazy`, your controller will not
be downloaded until the controller element first appears on the page.

* The `webpackMode` option in `controllers.json` was deprecated. Use
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should open a PR on UX and Flex to change this there. Do you have time to do it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already did! :) symfony/ux#53

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But flex - I hadn’t thought about that piece - I’ll get that done

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flex PR: symfony/flex#735

weaverryan added a commit to weaverryan/ux that referenced this pull request Feb 1, 2021
Keeping webpackMode for support of people using an old Flex version
@tgalopin
Copy link
Contributor

tgalopin commented Feb 1, 2021

Thanks Ryan.

@tgalopin tgalopin merged commit 5a7d462 into symfony:main Feb 1, 2021
tgalopin added a commit to symfony/ux that referenced this pull request Feb 1, 2021
…ge#15 (weaverryan)

This PR was merged into the main branch.

Discussion
----------

Changing webpackMode to fetch - see symfony/stimulus-bridge#15

| Q             | A
| ------------- | ---
| Bug fix?      | yes(ish)
| New feature?  | no
| Tickets       | none
| License       | MIT

Hi!

If symfony/stimulus-bridge#15 is merged, this updates the keys for all the UX packages.

The old `webpackMode` is kept for now. This will prevent errors if you're using an "old" Flex version (a version before this PR symfony/flex#735). We can remove that... eventually...

Cheers!

Commits
-------

27f7115 Adding fetch - see symfony/stimulus-bridge#15
symfony-splitter pushed a commit to symfony/ux-swup that referenced this pull request Feb 1, 2021
Keeping webpackMode for support of people using an old Flex version
symfony-splitter pushed a commit to symfony/ux-dropzone that referenced this pull request Feb 1, 2021
Keeping webpackMode for support of people using an old Flex version
symfony-splitter pushed a commit to symfony/ux-chartjs that referenced this pull request Feb 1, 2021
Keeping webpackMode for support of people using an old Flex version
symfony-splitter pushed a commit to symfony/ux-cropperjs that referenced this pull request Feb 1, 2021
Keeping webpackMode for support of people using an old Flex version
symfony-splitter pushed a commit to symfony/ux-lazy-image that referenced this pull request Feb 1, 2021
Keeping webpackMode for support of people using an old Flex version
tgalopin added a commit that referenced this pull request Feb 1, 2021
This PR was merged into the main branch.

Discussion
----------

Lazy controllers for user-land controllers

Hi!

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

```js
// 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:

```diff
// 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!

Commits
-------

bbf8ab0 Implementing a way to make user-land controllers lazy
tgalopin added a commit to symfony/flex that referenced this pull request Feb 2, 2021
… "fetch" mode (weaverryan)

This PR was merged into the 1.9-dev branch.

Discussion
----------

Changing to support next version of stimulus bridge with "fetch" mode

Partner to symfony/stimulus-bridge#15 and symfony/ux#53

The tricky part about this is that, if the user has `stimulus-bridge` 1.x, then their `controllers.json` file needs `webpackMode`. If they have `stimulus-bridge` "next" (we're thinking it'll be 2.0), then their `controllers.json` file needs `fetch`. This means that Flex has a "hard break" and sorta just needs to assume that the user has the "new" version.

We made the decision - to go from `webpackMode` to `fetch` because the setting no longer is truly the same as `webpackMode`. However, if we wanted to make the upgrade path easier, we could revert that and use `webpackMode` in 2.0 as well (instead of changing to `fetch`).

Commits
-------

0c452b5 Changing to support next version of stimulus bridge with "fetch" mode
weaverryan added a commit to symfony/ux that referenced this pull request Mar 15, 2021
…(kl3sk)

This PR was merged into the main branch.

Discussion
----------

Update README deprecated "webpackMode" in favor of "fetch"

After @weaverryan symfony/stimulus-bridge#15 PR

Encore complains:
`The "webpackMode" config key is deprecated in controllers.json. Use "fetch" instead, set to either "eager" or "lazy".`

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Tickets       | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT

<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.

Additionally (see https://symfony.com/releases):
 - Always add tests and ensure they pass.
 - Never break backward compatibility (see https://symfony.com/bc).
 - Features and deprecations must be submitted against branch main.
-->

Commits
-------

463f429 Update README.md
symfony-splitter pushed a commit to symfony/ux-dropzone that referenced this pull request Mar 15, 2021
After @weaverryan symfony/stimulus-bridge#15 PR

Encore complains:
`The "webpackMode" config key is deprecated in controllers.json. Use "fetch" instead, set to either "eager" or "lazy".`
Huskarhero added a commit to Huskarhero/ux-lazy-image that referenced this pull request Nov 17, 2022
jameswebapp added a commit to jameswebapp/ux that referenced this pull request Aug 1, 2023
Keeping webpackMode for support of people using an old Flex version
jameswebapp added a commit to jameswebapp/ux that referenced this pull request Aug 1, 2023
…ge#15 (weaverryan)

This PR was merged into the main branch.

Discussion
----------

Changing webpackMode to fetch - see symfony/stimulus-bridge#15

| Q             | A
| ------------- | ---
| Bug fix?      | yes(ish)
| New feature?  | no
| Tickets       | none
| License       | MIT

Hi!

If symfony/stimulus-bridge#15 is merged, this updates the keys for all the UX packages.

The old `webpackMode` is kept for now. This will prevent errors if you're using an "old" Flex version (a version before this PR symfony/flex#735). We can remove that... eventually...

Cheers!

Commits
-------

27f7115 Adding fetch - see symfony/stimulus-bridge#15
jameswebapp added a commit to jameswebapp/ux that referenced this pull request Aug 1, 2023
After @weaverryan symfony/stimulus-bridge#15 PR

Encore complains:
`The "webpackMode" config key is deprecated in controllers.json. Use "fetch" instead, set to either "eager" or "lazy".`
jameswebapp added a commit to jameswebapp/ux that referenced this pull request Aug 1, 2023
…(kl3sk)

This PR was merged into the main branch.

Discussion
----------

Update README deprecated "webpackMode" in favor of "fetch"

After @weaverryan symfony/stimulus-bridge#15 PR

Encore complains:
`The "webpackMode" config key is deprecated in controllers.json. Use "fetch" instead, set to either "eager" or "lazy".`

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Tickets       | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT

<!--
Replace this notice by a short README for your feature/bugfix. This will help people
understand your PR and can be used as a start for the documentation.

Additionally (see https://symfony.com/releases):
 - Always add tests and ensure they pass.
 - Never break backward compatibility (see https://symfony.com/bc).
 - Features and deprecations must be submitted against branch main.
-->

Commits
-------

463f429 Update README.md
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.

Lazy-load only the necessary controllers
3 participants