-
-
Notifications
You must be signed in to change notification settings - Fork 408
Introduce Template-only Class Components #1133
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
base: main
Are you sure you want to change the base?
Conversation
Is there a good reason to introduce a new concept instead of detecting if a standard component has no methods/properties except for the template and doing the optimisation to turn it into this? var Demo = template(`{{@value}}`, { scope: () => ({}) }); |
I was thinking the same thing as @evoactivity. Would be cool if we eliminated the template only paradigm entirely, everything is class based, then the class is optimized away when not needed. This is clearly way more complicated on the build, but I've heard from more than one person that the ember/no-empty-glimmer-component-classes rule is annoying as you don't really know when you get started with a component if you're going to need the backing class or not and there is a temptation to disable that rule. This rule is currently the only thing preventing me from doing this accidentally, and I'm glad for the rule, but it does point to a place where the mental model for components conflicts with the realities of build and performance. This RFC seems to point the same way. |
I mean, I think that's a great idea, and it means we only need to teach about a "for fun" detail that folks normally don't have to worry about. I like that better than what's written here and will update the RFC text to reflect |
Actually, I don't think that's possible without a breaking change. Consider: class A extends Component {
<template>
<B @state={{this}} />
</template>
}
class B extends Component {
get router() {
return getOwner(this.args.state).lookup('...');
}
<template>
{{this.router.currentURL}}
</template>
} Now... should someone do this? absolutely not. lol So naturally, we could say something more specific about the logic that governs when This requires that we fully parse the template contents during compilation -- which we currently don't do. The conversions to low-level class A {
static {
template(`<B @state={{this}} />`, {
component: this,
scope: () => ({ B })
});
}
} as proposed, we would ignore the So, this means only applications would get this optimization, as only in applications (where we would parse and compile the template anyway), could we determine if a Is this an ok trade-off? |
@jrjohnson I don't think we need to elimate the paradigm entirely since this is still useful const rowComp = <template><div>I'm row {{@data}}</div></template>; // <-- template only
class ThingWithRows extends Component {
rows = [...Array(20).keys()].map( i => i+1); ;
<template>
{{#each rows as |row|}}
<rowComp @data={{row}} />
{{/each}}
</template>
}
@NullVoxPopuli Could we just look in the string for any occurrence of |
I'm ok with this tradeoff, mainly because I think if you're authoring an add-on or some other way to include components into the application it's reasonable to assume you are willing to learn more stuff. But this difference between authoring an app and an add-on can get really difficult quickly. So it's probably not a great path to take unless we can lint the difference and encourage the behavior needed.
We certainly don't need to eliminate the |
I thought about that as well, but regex is hard, and it's why the v3 version of ember-template-imports was so buggy. Situations that'd be hard to deal with with regex:
|
@NullVoxPopuli this monstrosity seems to work in many cases but I take your point
|
Broke it for you :p https://regex101.com/r/aw8K9W/1 |
I fixed those cases but it's even worse now. Not exactly maintainable. I will code golf this no more 😄 |
wrote up a new one: #1134 |
potential alternative: // current: no generics!
export const Demo = <template>...</template>
// what Glint would want
// but doing this would require a component manager that hijacks all functions in component space
// (or we compile it away and forbid anything other than the <template></template>)
export function Demo<T>() {
return template(``)
}
// but our runtime is the equiv of
export const Demo = template('...');
// author-time???
export const Demo = <template type:{
<T extends Record<string, unknown>, K extends keyof T>() => {
Element: HTMLTextAreaElement;
Args: {
foo: T;
bar: K;
},
Blocks: {
default: []
}
}
}>...</template> |
Propose Template Only Class Components
Rendered
Summary
This pull request is proposing a new RFC.
To succeed, it will need to pass into the Exploring Stage, followed by the Accepted Stage.
A Proposed or Exploring RFC may also move to the Closed Stage if it is withdrawn by the author or if it is rejected by the Ember team. This requires an "FCP to Close" period.
An FCP is required before merging this PR to advance to Accepted.
Upon merging this PR, automation will open a draft PR for this RFC to move to the Ready for Released Stage.
Exploring Stage Description
This stage is entered when the Ember team believes the concept described in the RFC should be pursued, but the RFC may still need some more work, discussion, answers to open questions, and/or a champion before it can move to the next stage.
An RFC is moved into Exploring with consensus of the relevant teams. The relevant team expects to spend time helping to refine the proposal. The RFC remains a PR and will have an
Exploring
label applied.An Exploring RFC that is successfully completed can move to Accepted with an FCP is required as in the existing process. It may also be moved to Closed with an FCP.
Accepted Stage Description
To move into the "accepted stage" the RFC must have complete prose and have successfully passed through an "FCP to Accept" period in which the community has weighed in and consensus has been achieved on the direction. The relevant teams believe that the proposal is well-specified and ready for implementation. The RFC has a champion within one of the relevant teams.
If there are unanswered questions, we have outlined them and expect that they will be answered before Ready for Release.
When the RFC is accepted, the PR will be merged, and automation will open a new PR to move the RFC to the Ready for Release stage. That PR should be used to track implementation progress and gain consensus to move to the next stage.
Checklist to move to Exploring
S-Proposed
is removed from the PR and the labelS-Exploring
is added.Checklist to move to Accepted
Final Comment Period
label has been added to start the FCP