-
Notifications
You must be signed in to change notification settings - Fork 186
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
v3: upgrade guide decorator section #1199
Conversation
A live preview of this PR will be available at the URL(s) below. https://pr1199-2799c11---lit-dev-5ftespv5na-uc.a.run.app/docs/v3/releases/upgrade/ |
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.
Some initial comments
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.
Some more suggestions. I'm happy to make the changes and push to the branch myself too.
decorators, etc., from one version of Lit will work with those from another. | ||
Lit 2.x and 3.0 are _interoperable_: templates, base classes, and directives from one version of Lit will work with those from another. | ||
|
||
## Decorator behavior has been unified |
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.
I think this section should be titled something more generic like "Updates to Lit decorators"
Lit 2 decorators were written to work with TypeScript's experimental decorators ("experimentalDecorators": true
in tsconfig), and Babel (@babel/plugin-proposal-decorators
) with version: "2018-09"
.
Lit 3 decorators remove support for Babel with version: "2018-09"
and adds support for standard JavaScript decorators, while still supporting TypeScript experimental decorators.
In Lit 3.0 our decorators support running in three configurations: | ||
|
||
1. With the TypeScript `experimentalDecorators` flag and properties without the `accessor` keyword. This is backwards compatible with Lit 2 users. As standard decorators are still immature, this is the most performant option that we recommend for production for the time being. | ||
2. With the TypeScript `experimentalDecorators` flag and with the `accessor` keyword. This aids migration to standard decorators. Code can add the `accessor` keyword one decorator at a time to migrate gradually. | ||
3. As standard decorators, which need the `accessor` keyword, and TypeScript 5.2 (without the `experimentalDecorators` flag), or Babel 7.23.0. |
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.
I think it's potentially a bit confusing to call this three configurations.
Configuration-wise, it's really 2 cases:
- TypeScript experimental decorators (with
"experimentalDecorators": true
and"useDefineForClassFields": false
in tsconfig) - TC39 standard decorators with metadata (available with TypeScript 5.2 or Babel 7.23.0)
(Then we should skip to "To make Lit decorators consistent..." with the list of breaking changes.)
To use the standard decorator configuration, @property()
decorated class fields must include the accessor
keyword. (Link to a new entry in "## Steps to Upgrade" section showing code change needed.)
To aid in migration from experimental decorators to standard decorators, decorated class fields with the accessor
keyword will also work with the experimentalDecorators
flag set to true. So users can start migrating code without changing the TS configuration.
(Then we should include the snippet suggested by Peter about recommending users stick to experimental decorators for the time being.)
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.
Yeah, configuraitons is a bit confusing, it suggests a build tool config. I think we should document these three cases though. What about:
In Lit 3.0 there are three supported ways to use our decorators:
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.
Also, maybe we should put the big idea up front in bold:
The Lit 3 decorators are largely backwards compatible. If you've been using them with TypeScript, **most likely no changes are needed**. We've added forward compatibility with standard decorators, but the legacy `experimentalDecorators: true` without the `accessor` keyword is currently the more performant option.
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.
Hmm.. While I believe we should definitely mention that accessor
fields work with experimental decorator config, I don't know if I would call it out in a list of 3 "supported ways" like that. In that sense, writing separate getter setter and decorating the setter is also a "supported way" of using our decorators.
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.
However, a valid 3rd configuration is
{
"experimentalDecorators": true,
"useDefineForClassFields": true
}
with decorated fields using accessor
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.
And also speaking of configuration, I think we should make clear that standard decorator support for TypeScript is currently strictly tsc
only. esbuild
and swc
do not yet have all the necessary implementations. This means Vite projects can't have tsconfigs that don't set experimental decorators. Maybe this belongs in the launch blog post, rather than the upgrade guide.. but is certainly another reason to recommend sticking to experimental decorators.
2. With the TypeScript `experimentalDecorators` flag and with the `accessor` keyword. This aids migration to standard decorators. Code can add the `accessor` keyword one decorator at a time to migrate gradually. | ||
3. As standard decorators, which need the `accessor` keyword, and TypeScript 5.2 (without the `experimentalDecorators` flag), or Babel 7.23.0. | ||
|
||
Each of these configurations is self contained. An application can mix and match libraries written in each of these configurations, and it is not generally a breaking change for a library to switch from one decorator configuration to another. |
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.
I don't think this statement is necessarily true as written.
Libraries compiled with different configurations are interchangeable, i.e. internal decorators are fine, but different decorator implementations are not mixable.
So libraries that export decorators, unless they make it hybrid, will incur breaking change when switching from one to another. If a project uses lit decorators and mobx decorators, for instance, they need to choose a config that satisfies both decorator implementations.
I would vote we remove this line.
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.
configurations
is making this confusing I think. I think it's important that we keep this paragraph. How about this wording:
Whether and how it uses the Lit decorators is an internal implementation detail of a Lit element. An application can mix and match libraries written in each of these styles, and it is not generally a breaking change for an element to switch from one decorator style to another.
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.
Ah, I see. You're targeting component authors with this statement. The word "libraries" is throwing me off more so than "configurations" as I think of things like lit and mobx when I hear libraries.
An application can mix and match
libraries written incomponents built with each of thesestylesconfigurations
However, I do think this can be misleading to application developers writing their own components (and possibly their own decorators) because switching decorator config for them is a big deal that affects the entire project.
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.
Yeah but if you're using other decorators and you change the tsconfig, you'll get a bunch of type errors for those decorators. It's a self-documenting problem.
The TypeScript error could definitely be clearer though: https://www.typescriptlang.org/play?&experimentalDecorators=true#code/MYewdgzgLgBApgDwA5wE4EsC2cxQIYA2AInMDALwwAUAUDPTEqiFCAFwwgBGAVqVABo6DMHmwcACsxSooATwDScOTQCUFAHwwA3sPoB6fTCxICxzKZoBfANw0awAnggQYAMRAgdemAAFEMlg4+MSkMABmnhQwAOQAFugxdlZAA
The thing I want to convey here is that an app doesn't have to care about its libraries, and libraries don't have to care about their dependents. This makes the entire thing 10,000% more chill
2f65306
to
fa09a43
Compare
I tried to thread the needle on the decorator feedback, to get all the required points across. Also needed to rebase to get the new changes. |
1. With the TypeScript `experimentalDecorators` flag and properties without the `accessor` keyword. This is backwards compatible with Lit 2. | ||
2. With the TypeScript `experimentalDecorators` flag and using the `accessor` keyword. This aids migration to standard decorators. [Code can add the `accessor` keyword one decorator at a time to migrate gradually](#standard-decorator-migration). |
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.
Can we add to 1. that useDefineForClassField
must be false, and in 2. useDefineForClassField
can be true (default for target 2022 or higher)?
And maybe worth stating accessor
keyword requires TS 4.9?
- `requestUpdate()` is called automatically for `@property()` and `@state()` decorated | ||
accessors where previously that was the setters responsibility. | ||
- The value of an accessor is read on first render and used as the initial value for `changedProperties` and attribute reflection. | ||
- Lit 3 decorators do not support Babel (`@babel/plugin-proposal-decorators`) with `version: "2018-09"`. |
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.
I think it would be good to also state the alternative.
- Lit 3 decorators do not support Babel (`@babel/plugin-proposal-decorators`) with `version: "2018-09"`. | |
- Lit 3 decorators no longer support `version: "2018-09"` option of `@babel/plugin-proposal-decorators`. Babel users should instead [migrate](#standard-decorator-migration) to use `version: "2023-05"` with plugin version greater than 7.23.0 which follows the TC39 standard decorator spec. |
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 should also say that this requires using the accessor
keyword too
There is some amazing decorator information being discussed here. I wonder if we're trying to fit all the decorator information into the upgrade guide, where instead we may want to split the information between "upgrading from Lit 2.0", and adding detailed docs to the v3 decorator documentation? Here in the upgrade guide I think the most important decorator information is the behavior changes to In a way, the upgrade guide might not even need to mention standard decorators, because users upgrading from Lit 2 don't even need to upgrade to standard decorators for Lit 3 to work well. We even don't want to encourage standard decorators yet. wdyt? |
This is an excellent point and I agree. Focus of the migration guide should be addressing breaking changes, not new features. Info dump can be moved to the decorators page of the docs. |
I've done quite a massive change, by focussing down the upgrade guide to only cover the "breaking changes" of experimental decorators. Then I'll take the other comments and add them to a decorator page section. |
Co-authored-by: Justin Fagnani <[email protected]>
Co-authored-by: Justin Fagnani <[email protected]>
Co-authored-by: Justin Fagnani <[email protected]>
Co-authored-by: Justin Fagnani <[email protected]>
Co-authored-by: Justin Fagnani <[email protected]>
Co-authored-by: Justin Fagnani <[email protected]>
Co-authored-by: Justin Fagnani <[email protected]>
This is ready for re-review! Preview: https://pr1199-2799c11---lit-dev-5ftespv5na-uc.a.run.app/docs/v3/releases/upgrade/ |
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.
Looking good. Just a few minor changes.
Co-authored-by: Augustine Kim <[email protected]>
Co-authored-by: Augustine Kim <[email protected]>
Co-authored-by: Augustine Kim <[email protected]>
Co-authored-by: Augustine Kim <[email protected]>
Issue: #1189
This PR specifically addresses the decorator section.
Context
Since this guide was last written, we now have hybrid decorators that are compatible with both experimental and standard decorator environments.
This change updates the guidance to include the breaking changes in experimental decorators.
Other changes:
Upgrade to Lit 3.x guide
.requestUpdate
.Release plan
Note this can be merged directly to main, as it's scoped to the
v3
documentation.Tested
Manually via preview link.
Thank you!