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

Add mixins support to the _decorate helper #9166

Merged

Conversation

nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Dec 11, 2018

Q                       A
License MIT

The decorators transform has a very big runtime helper: almost every change to the proposal will impact the runtime behavior.
There are already different cases where we shouldn't enable some decorators functionality by default:

  1. Private elements (Add support for decorators with private elements - Spec mode #9154): They should only be enabled if either the class-properties or private-methods plugins are enabled. Also, there should be two different versions: spec and loose.
  2. Initializers ([decorators] Add support for initializers #9008): TC39 agreed that their functionality should be introduced, but their name is likely to change. We should only introduce them using an opt-in flag.
  3. Many features proposed to the decorators champions have been deferred as follow-on proposals: we shouldn't enable them by default when we will implement them.
  4. The proposal could still be subject to breaking changes, which until Babel 8 should be opt-in.

I considered three ways of handling this runtime flags:

  1. Pass the flags to the _decorate helper and implement everything there.
    Pro: It is probably easier to maintain
    Con: The helper will became bigger and bigger, since we will need to include, at least, 1. initializers, 2. spec PrivateName, and 3. loose PrivateName
  2. Inject the needed features as parameters: this is what I currently did for Add support for decorators with private elements - Spec mode #9154 to allow swapping between spec mode and loose mode (only the former is implemented in that PR).
    Con: It won't scale well with different runtime flags
  3. Allow extending the _decorators helper using completely separated helpers, using mixins. This is what I implemented in this PR.
    Pro: Only needed helpers will be added to the output code.
    Con: Harder to maintain that option 1.

I rewrote #9008 using this new pattern, you can see how it works at nicolo-ribaudo/babel@66cbf54


How to review this PR:

The only meaningful changes introduced by this PR are inside the _decorate function. Everything else is just moving all the functions to the api objects and change function calls from _foo() to this.foo().
What is most important is whether you think that this mixins pattern is ok or not.

@nicolo-ribaudo nicolo-ribaudo added PR: Internal 🏠 A type of pull request used for our changelog categories Spec: Decorators labels Dec 11, 2018
@nicolo-ribaudo nicolo-ribaudo added this to To do in Class features via automation Dec 11, 2018
@nicolo-ribaudo nicolo-ribaudo moved this from To do to In progress in Class features Dec 11, 2018
@babel-bot
Copy link
Collaborator

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/9599/

@danez
Copy link
Member

danez commented Dec 13, 2018

We could use decorators instead of mixins 😝
I have never before worked with the helpers, but the general approach of being able to compose helpers with the needed functionality seems good to me. The change seems actually more similar to React High Order Components than the really old react mixins.

Con: Harder to maintain that option 1.

If I understand it correctly it might be hard though at some point when there are multiple mixins and they all have to stay compatible to each other. I guess at least we can make sure they will always be applied in the same order. We should make sure we have enough runtime tests for all the combinations.

But as I said I don't know much about helpers nor about the concrete status of the decorators proposal.

@nicolo-ribaudo
Copy link
Member Author

If I understand it correctly it might be hard though at some point when there are multiple mixins and they all have to stay compatible to each other. I guess at least we can make sure they will always be applied in the same order. We should make sure we have enough runtime tests for all the combinations.

Yeah exactly, the number of possible combinations will grow exponentially. I guess we should just be good and write all the needed tests.

@nicolo-ribaudo
Copy link
Member Author

I'm merging this so that I can rebase the privates and initializers PRs, and because the actual changes are quite small:

var api = _getDecoratorsApi();
if (mixins) {
for (var i = 0; i < mixins.length; i++) {
api = mixins[i](api);
}
}

If you have any concern, we can follow-up.

@nicolo-ribaudo nicolo-ribaudo merged commit 9d1d0fe into babel:master Dec 29, 2018
Class features automation moved this from In progress to Done Dec 29, 2018
@nicolo-ribaudo nicolo-ribaudo deleted the decorators-helper-mixins branch December 29, 2018 21:54
nicolo-ribaudo added a commit to nicolo-ribaudo/babel that referenced this pull request Jan 16, 2019
@nicolo-ribaudo nicolo-ribaudo mentioned this pull request Jan 18, 2019
6 tasks
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 4, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Internal 🏠 A type of pull request used for our changelog categories Spec: Decorators
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

3 participants