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

v3: upgrade guide decorator section #1199

Merged
merged 22 commits into from
Oct 6, 2023
Merged

Conversation

AndrewJakubowicz
Copy link
Contributor

@AndrewJakubowicz AndrewJakubowicz commented Oct 2, 2023

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:

  • Add a link to the v2 upgrade guide on the top.
  • Rename the upgrade guide to Upgrade to Lit 3.x guide.
  • Update the custom accessor guidance. You no longer need to call 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!

@github-actions
Copy link

github-actions bot commented Oct 2, 2023

A live preview of this PR will be available at the URL(s) below.
The latest URL will be appended to this comment on each push.
Each build takes ~5-10 minutes, and will 404 until finished.

https://pr1199-2799c11---lit-dev-5ftespv5na-uc.a.run.app/docs/v3/releases/upgrade/
https://pr1199-0981c31---lit-dev-5ftespv5na-uc.a.run.app/
https://pr1199-59d116a---lit-dev-5ftespv5na-uc.a.run.app/
https://pr1199-6f3317e---lit-dev-5ftespv5na-uc.a.run.app/
https://pr1199-5d3dcac---lit-dev-5ftespv5na-uc.a.run.app/

rictic
rictic previously requested changes Oct 3, 2023
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
Copy link
Member

@augustjk augustjk left a comment

Choose a reason for hiding this comment

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

Some initial comments

packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
Copy link
Member

@augustjk augustjk left a 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
Copy link
Member

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.

Comment on lines 36 to 42
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.
Copy link
Member

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:

  1. TypeScript experimental decorators (with "experimentalDecorators": true and "useDefineForClassFields": false in tsconfig)
  2. 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.)

Copy link
Contributor

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:

Copy link
Contributor

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.

Copy link
Member

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.

Copy link
Member

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

Copy link
Member

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.
Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Member

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 in components built with each of these styles configurations

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.

Copy link
Contributor

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

packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
@AndrewJakubowicz
Copy link
Contributor Author

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.

Comment on lines 40 to 41
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).
Copy link
Member

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"`.
Copy link
Member

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.

Suggested change
- 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.

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 also say that this requires using the accessor keyword too

@AndrewJakubowicz
Copy link
Contributor Author

AndrewJakubowicz commented Oct 5, 2023

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 experimentalDecorators: true, without accessor. Otherwise I think the detailed docs about decorators and the different configurations might be better suited in the v3 decorator docs?

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?

@augustjk
Copy link
Member

augustjk commented Oct 5, 2023

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.

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.

@AndrewJakubowicz
Copy link
Contributor Author

AndrewJakubowicz commented Oct 5, 2023

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.

@AndrewJakubowicz
Copy link
Contributor Author

This is ready for re-review!
Thank you!

Preview: https://pr1199-2799c11---lit-dev-5ftespv5na-uc.a.run.app/docs/v3/releases/upgrade/

@AndrewJakubowicz AndrewJakubowicz dismissed rictic’s stale review October 6, 2023 19:00

major changes have happened

@AndrewJakubowicz AndrewJakubowicz changed the title Update the v3 upgrade guide, and v3 custom accessor guidance v3 upgrade guide decorator guidance, and v3 custom accessor guidance Oct 6, 2023
@AndrewJakubowicz AndrewJakubowicz changed the title v3 upgrade guide decorator guidance, and v3 custom accessor guidance v3: upgrade guide decorator section Oct 6, 2023
Copy link
Member

@augustjk augustjk left a 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.

packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
packages/lit-dev-content/site/docs/v3/releases/upgrade.md Outdated Show resolved Hide resolved
@AndrewJakubowicz AndrewJakubowicz merged commit c17b3e6 into main Oct 6, 2023
14 of 15 checks passed
@AndrewJakubowicz AndrewJakubowicz deleted the update-upgrade-guide branch October 6, 2023 23:46
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.

4 participants