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
chore: migration to TC39 decorators + metadata simplification #1932
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @Sayan751, we are on final steps to RC with this. I've had a few comments mostly around the API changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the replies, I think I agree on the initializer part, we can just let all our decorator wait until the initializer phase and call the define
, so we can just deal with Symbol.metadata
instead of having to drag context everywhere.
b6ee095
to
89e2983
Compare
998cdc7
to
d913e41
Compare
d913e41
to
0fb0881
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1932 +/- ##
==========================================
- Coverage 88.63% 88.43% -0.21%
==========================================
Files 261 262 +1
Lines 22862 22689 -173
Branches 5320 5283 -37
==========================================
- Hits 20264 20064 -200
- Misses 2598 2625 +27 ☔ View full report in Codecov by Sentry. |
@bigopon it is ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @Sayan751 , only a last few comments.
defineAttribute({ name: 'default-case', bindables, isTemplateController: true }, DefaultCase); | ||
defineAttribute({ name: 'case', bindables, isTemplateController: true }, Case); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this makes me realized it's an oversight that static $au
is trying to support inheritance. It should be checking own static $au
only, similar for the cached data of static au. Maybe we can add that in this PR to avoid having to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. The issue is slightly different. Once we define the metadata in Class[Symbol.metadata]
(it is irrelevant how it is defined) on a parent class, it is inherited by the child class. And that causes the problem. From a different angle, it is a reasonable design that the child inherits the parents' metadata. If you want to override that, you can do so by using decorators, and the generated code for that will take care of it. But in the absence of a decorator, the metadata gets inherited, and that seems reasonable. If we had used decorators directly in our core code, ignoring the bundle size aspect, such gymnastic, like the code in question, would not be necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use static blocks, so that the code will stay with the definition and we won't have to deal with loose calls like this, it'll help with tree shaking I believe.
For inheritance, I'm not sure the implication of such free flow, but I don't have a way to explore the scenarios yet, so may be it'll be like this until we will have figured out something else.
@Sayan751 I'll go ahead with the merge, the rest of the comments are minor non blocking, we can continue the discussion here and get them in later. Fantastic work 👍 |
cleanup work for some discussion points in #1932 [skip ci]
2.0.0-beta.15 (2024-04-17) A step closer to RC **BREAKING CHANGES:** * **expression-parser:** move exp parser to its own package (#1943) ([6e7dcad](6e7dcad)) * **bindings:** move binding infra to runtime html (#1944) ([1c7608a](1c7608a)) * **runtime:** migration to TC39 decorators + metadata simplification (#1932) ([22f90ad](22f90ad)) **Features:** * **resources:** support static `$au` property for definition (#1939) ([877a385](877a385)) **Bug Fixes:** * **ts-jest:** add isolated modules for internal ts-jest instance (#1941) ([7eb31f4](7eb31f4)) * **vite-plugin:** missed some default options in "load" preprocess (#1936) ([794f3c6](794f3c6)) * **vite-plugin:** when using ShadowDOM, need to load css as string (#1934) ([32e8cc1](32e8cc1))
@Sayan751 @bigopon hey guys, it would be helpful to get more details of the migration in either the PR or the release (preferable in the release) when an impactful breaking change like this one comes into play. I'm trying hard to keep my open source project Aurelia-Slickgrid up to date with Aurelia 2 but there's breaking change at every beta without much migration info (none in this case). After looking at the PR and searching for something similar to my code, like - constructor(@I18N private readonly i18n: I18N) {
+ constructor(private readonly i18n: I18N = resolve(I18N)) { or this other line - constructor(@newInstanceOf(IHttpClient) readonly http: IHttpClient) {
+ constructor(readonly http: IHttpClient = resolve(newInstanceOf(IHttpClient))) { Showing these kind of changes would be really helpful to be displayed directly in the release (or at the minimum in the PR). Angular, esbuild, they all do that in their release and it's very helpful and quicker to migrate. It also seem like we need to modify our |
@ghiscoding You are absolutely right. It is my bad. I have plan to update the docs, but I am yet to do so. For now, I have updated the release notes with relevant details. Thank you for drawing our attention to this. |
Thanks for that and all the work you do on Aurelia 2 :) |
Added another point related to coercing in the release notes. |
@Sayan751 @bigopon Hi guys. I am also a maintainer of an open-source project, NetPad, that is built using Aurelia 2 and appreciate you adding some documentation on this. I rely pretty heavily on decorators for all my constructor injection and after reviewing the changes I had a few questions before I embark on the non-trivial changes to the codebase needed for this update: 1. You mention that
Will parameter decorators eventually be supported, and thus be brought back to Au2 before release? Or is that up in the air. If the former, I'd rather hold off on upgrading to beta15 and wait for when they come back(?) 2. Migration instructions for parameter decorators is to use the I'd rather keep the class property in the constructor and use the 3. You mention that
Just want to confirm that built-in decorators like 4. Lastly, what about decorators applied to classes or methods. Are those affected by this as well? ie. For built-in decorators they are fine, but custom one need to be migrated as shown in linked articles? Thank you guys for all the amazing work you do on Aurelia 2. Really love the framework and try to push it in business settings. |
@tareqimbasher on my side, all the |
Thank you @ghiscoding for the input and the PR, will take a look. I'm upgrading from beta.7 and currently got it working up to beta.14 besides a bug I'm trying to figure out related to the changes with Also great lib, Aurelia-Slickgrid, looking forward to using it soon! |
That purely depends on whether and when this proposal reaches stage 3. It is out of our control to predict anything on that front. But yes, once the proposal is standardized, we will be glad to bring back parameter decorators. However, if I remember correctly, only the DI-related decorators were parameter decorators. You can easily replace those using
Feel free to do so. The release note merely shows both possibilities. Plus, if those are classes are meant for inheritance, avoiding ctor parameters in the base class, makes it easier (less code) for the child class. Having said that, you can very well do something like below. import { resolve } from 'aurelia';
class MyClass {
public constructor(
private readonly bar: IBar = resolve(IBar),
) { }
}
That is correct. Apart from the parameter decorators, every other decorator should be as it was before this change.
That is correct. If you have written any (experimental/TS) decorators, those needs to be migrated to the new proposal. Here is an example, how we migrated our decorators at work. Happy Migration! ✌️ |
@Sayan751 Thank you for the detailed response! |
with the completion of the decorator migration, RC is considered around the corner. We will have a few more beta versions as "buffer" to be safe, and to resolve potential issues with the new decorator implementation. The decorator proposal also getting new capabilities considered so it's not even bad for us to delay a bit.
Thanks for the reminder @ghiscoding , I should say that while there' breaking changes, it's not the kind of changes that rock your apps, so the benefit of having checkpoints for applications to migrate will be appreciated later (at least from the maintainers perspective, maybe they'll be cursed less), especially there' probably many apps in that category. |
📖 Description
With the certain outlook of the TC39 decorator moving to stage 4, we need to start preparing our decorators to follow this new spec.
The work of moving all the decorators in the framework to the new spec will be:
🎫 Issues
Closes #1180
Decorator migration guide
tsconfig.json
:"emitDecoratorMetadata": true
and"experimentalDecorators": true
. This activates the native/TC39 decorator.target
property is set to something lower thanesnext
. If this is set toesnext
, then TypeScript assumes reasonably that the target runtime supports decorators natively, and hence does not transpile those.resolve
function.emitDecoratorMetadata: true
microsoft/TypeScript#57533 for more information. For now, you can explicitly specify the type when declaring bindables.