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

Implement 2022.3/Stage 3 Decorator Support #3638

Closed
wants to merge 11 commits into from

Conversation

Matchlighter
Copy link
Collaborator

@Matchlighter Matchlighter commented Feb 24, 2023

Title kind of speaks for itself on this one.

Prior conversation has taken place in a discussion here: #3373 (comment)

Code change checklist

  • Added/updated unit tests
  • Updated /docs. For new functionality, at least API.md should be updated
  • Verified that there is no significant performance drop (yarn mobx test:performance)
  • Finish writing unit tests
  • Cleanup

@changeset-bot
Copy link

changeset-bot bot commented Feb 24, 2023

🦋 Changeset detected

Latest commit: 78bee62

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
mobx Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Member

@mweststrate mweststrate left a comment

Choose a reason for hiding this comment

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

Thanks @Matchlighter for picking this up! Looking quite sane so far, left a bunch of questions!

packages/mobx/src/api/action.ts Outdated Show resolved Hide resolved
packages/mobx/src/api/action.ts Show resolved Hide resolved
packages/mobx/src/types/actionannotation.ts Outdated Show resolved Hide resolved
packages/mobx/src/types/actionannotation.ts Outdated Show resolved Hide resolved
packages/mobx/src/types/actionannotation.ts Outdated Show resolved Hide resolved
packages/mobx/src/types/computedannotation.ts Show resolved Hide resolved
packages/mobx/src/types/computedannotation.ts Outdated Show resolved Hide resolved
packages/mobx/src/types/observableannotation.ts Outdated Show resolved Hide resolved
packages/mobx/src/types/observableannotation.ts Outdated Show resolved Hide resolved
packages/mobx/src/types/observableannotation.ts Outdated Show resolved Hide resolved
@Matchlighter Matchlighter force-pushed the decorators2022 branch 7 times, most recently from 6f41744 to 5ce0269 Compare February 28, 2023 18:48
@Matchlighter
Copy link
Collaborator Author

Just pushed another patchset. All tests are passing locally (except eslint ones, which I haven't touched and are also giving me trouble when I run them against main branch). Everything should be pretty much done except some of the design decisions around enumerability.

@mweststrate
Copy link
Member

Thanks for the awesome work so far @Matchlighter! The coming two weeks I'm too busy to give this PR the proper attention to wrap it up, push it forward etc, but I think this is strongly heading in the right direction, so feel free to already update docs etc. My plan is to first unblock @urugator on the React 18 work half March (#3590) and then I'll focus on decorators. (I'm feeling quite the bottleneck now😅)

@Matchlighter
Copy link
Collaborator Author

@mweststrate All good! I'm getting a bit busy too so it works well! I'll go ahead and work on getting things cleaned up and updating docs over then next week or so.

@Matchlighter Matchlighter force-pushed the decorators2022 branch 6 times, most recently from 6de073c to 0908ca6 Compare March 12, 2023 05:13
@Matchlighter
Copy link
Collaborator Author

Matchlighter commented Mar 12, 2023

Pushed a new change with updated doc and with local builds/tests completing successfully. It appears there's a regression in the type-checker's module resolution logic in the TypeScript 5.0 Beta and RC, but it's corrected in the nightly, so I bumped the TS resolution up to the most recent (as of writing this) nightly. There's also a (non-critical) TODO regarding eslint - it warns about being incompatible with TS 5, but otherwise works - will need to bump the typescript-eslint package(s) once it accepts TS 5 w/o warning to reduce log-spam when running tests.

@Matchlighter Matchlighter marked this pull request as ready for review March 12, 2023 05:17
@iChenLei
Copy link
Member

Run yarn --frozen-lockfile --ignore-scripts
yarn install v1.22.19
[1/4] Resolving packages...
warning Resolution field "typescript@5.1.0-dev.20230311" is incompatible with requested version "typescript@^3.7.3"
warning Lockfile has incorrect entry for "typescript@^5.0.0-beta". Ignoring it.
warning Resolution field "[email protected]" is incompatible with requested version "typescript@^5.0.0-beta"
error Your lockfile needs to be updated, but yarn was run with --frozen-lockfile.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Error: Process completed with exit code 1.

@Matchlighter
Copy link
Collaborator Author

Matchlighter commented Mar 12, 2023

Wuh...? Latest yarn.lock is checked-in - running yarn doesn't change the yarn.lock file. Anyway, here's a tweak that looks like it helps that

Hrm. Seeing an issue with something about getMutableClone only when run by CI. Will look into tomorrow.

@kubk
Copy link
Collaborator

kubk commented Mar 13, 2023

@Matchlighter Thank you so much for the PR. Just for you to know, you don't have to squash and force push all the time, cause we merge PRs with "squash" flag enabled. It seems like because of force push GitHub always requires us to approve and run your PR while usually it's enough to approve only once. I'll approve again.

@Matchlighter
Copy link
Collaborator Author

Ahh, gotcha. 👍

@Amareis
Copy link
Contributor

Amareis commented Mar 22, 2023

@Matchlighter you can bump TS to 5.0.2, it's released now.

@Matchlighter
Copy link
Collaborator Author

@Amareis I've updated things, but I've discovered what seems to be a bug in TS 5.0.2 that wasn't present in the betas. I've submitted microsoft/TypeScript#53448 that was caught by one of MobX's specs. I've worked around it in the spec for now.

@Amareis
Copy link
Contributor

Amareis commented Mar 23, 2023

One question about field actions (@action field = () => {}) - why does this require makeObservable? You can just return (mthd) => _createAction(mthd) and everything will work as intended. I use this syntax in some places and it will silently break after migration, which is not good IMHO.

@Matchlighter
Copy link
Collaborator Author

Matchlighter commented May 26, 2023

@kubk Is that CI error a known issue? It doesn't really seem to be related and I'm unable to repro locally.

@urugator
Copy link
Collaborator

urugator commented May 27, 2023

@Matchlighter This test is unfortunately timing sensitive, it waits for GC. Was trying to find some reasonable value for the timeout, but it still occasionally fails depending on CI workload. Feel free to change it to 5000ms or whatever passes.

@Matchlighter
Copy link
Collaborator Author

Matchlighter commented May 27, 2023

@urugator Ah gotcha. I'll try playing with it. I know there's a hook in Node to force a GC - I'll try that and then try timing.

Edit: Ah you're already using that. Seems weird that it's not immediate - the project I used it in, it was reliably done by the next run of the event loop.

@derekcannon
Copy link

If makeObservable will not be required for the new decorators, does that mean we can mix annotation super classes with decorated child classes? Currently, there's an exception thrown about using makeObservable with the second argument when using decorators in a child class.

@Matchlighter
Copy link
Collaborator Author

@mweststrate Do you have an updated timeline of when you can look at this?

@mweststrate
Copy link
Member

@Matchlighter sorry, I've been terrible swamped lately. But I expect we can release #3673 in the coming days, then I'll pick this one up first thing. Again apologies for being the bottleneck and the delay in reviewing your awesome work!

@mweststrate
Copy link
Member

@Matchlighter Sorry, the React work hit more bumps than we hoped. The React work is not entirely wrapped up, but I think the remaining changes are local enough to be able to safely rebase this branch. Are you able to look into that or do you want me to take care of that?

Copy link
Member

@mweststrate mweststrate left a comment

Choose a reason for hiding this comment

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

Again, such an awesome job you did here @Matchlighter! I left a bunch of comments, but overall things look really good. I still want to give it a manual test drive, but beyond that I don't think much is in the way of releasing.

I'll send you a maintainers invite as well, that makes it a bit easier to contribute in the future as you can directly write to the repo. Feel free to reject or accept!

Also, again super sorry this is taking so long. You've put a lot of effort in here, it didn't deserve to be on the shelve for so long. Also, note that we can sponsor significant contributions, let me know via DM / mail if you want to make use of that!

docs/enabling-decorators.md Outdated Show resolved Hide resolved
docs/enabling-decorators.md Show resolved Hide resolved
docs/enabling-decorators.md Show resolved Hide resolved
docs/enabling-decorators.md Show resolved Hide resolved
"tsdx": "^0.14.1",
"typescript": "^4.0.2"
"typescript": "^5.0.2"
Copy link
Member

Choose a reason for hiding this comment

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

If it is little hastle, it could be interesting to split out the tooling & infra updates (Jest and TS) from the actual changes as separate PR, which we can land quickly, given that space wise the largest updates is coming from Jest, it might be nice to have that hitched down before landing decorators, to be able to more easily roll back if needed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oof. That would have been a good thought for me to think of... I'll see what I can do.

})
})

test("verify object assign (2022.3) (legacy/field decorator)", () => {
Copy link
Member

Choose a reason for hiding this comment

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

idem

packages/mobx/src/types/decorator_fills.ts Show resolved Hide resolved
packages/mobx/src/types/flowannotation.ts Show resolved Hide resolved
packages/mobx/src/types/observableannotation.ts Outdated Show resolved Hide resolved
false
)
adm.values_.set(name, observable)
initializedObjects.add(target)
Copy link
Member

Choose a reason for hiding this comment

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

asObservableObject is idempotent, so I'm not 100% we need the initializedObjects? This feels a bit irky, but probably that can possibly be optimised later, fine for now I guess. I imagine we could do a check with asObservableObject(target)[$mobx].values_.has if we still need to init.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That works too. This approach mimics how TS handles some of the accessor stuff in the transpiled code.

Copy link
Member

Choose a reason for hiding this comment

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

Reviving this discussion, it seems this might still change in the spec: tc39/proposal-decorators#513

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm crossing my fingers! That changing would make this so much cleaner (and probably a little faster since we'll avoid the has() call

@mweststrate mweststrate requested a review from urugator July 25, 2023 19:33
@Matchlighter
Copy link
Collaborator Author

Thanks for the review - I'll take a look in the next few hours. Looks like you already rebased 👍 .

Copy link
Member

@mweststrate mweststrate left a comment

Choose a reason for hiding this comment

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

Preliminary approval. Still want to do some manual testing and land the React fixes first.

Also cc @urugator love your thoughts on this if interested :) (if you can't manage no worries!)

addInitializer(function () {
storeAnnotation(this, name, ann)
})
return
Copy link
Contributor

Choose a reason for hiding this comment

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

it would be great if there was a config option to forbid this or at least warn. seems to me that it will just be confusing when you have a code base and forget the accessor modifier and it just silently breaks


## MobX Core decorators {🚀}

MobX before version 6 encouraged the use of ES.next decorators to mark things as `observable`, `computed` and `action`. While MobX 6 recommends against using these decorators (and instead using [`makeObservable` / `makeAutoObservable`](observable-state.md)), it is still possible.
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems a bit confusing. Are they recommended for use now or not? Maybe this section should be titled "legacy decorators" and the text changed?

Copy link
Member

Choose a reason for hiding this comment

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

Good call! I'll went to the docs and there is still some more straightening out to do, but we're close!

@mweststrate
Copy link
Member

The whole mobx-react update took a bit longer than planned 😅, but it has been released, so if it is stable for ~week we can continue with this one finally! I noticed it requires some more doc finetuning, I will follow up on that. Otherwise things look complete :)

@TomasChmelik
Copy link

Any news on this? I can't wait for the decorator support for MobX ❤️

@mweststrate
Copy link
Member

mweststrate commented Oct 11, 2023 via email

@mweststrate
Copy link
Member

mweststrate commented Oct 20, 2023

[email protected] Now has experimental support available! An example migration commit can be found here:

Let us know if you run into any issues.

Most important migration steps

  1. TypeScript must be 5 or higher.
  2. TypeScript target must be ES2015 or higher
  3. Set TS option experimentalDecorators: false if it was true.
  4. Don't forget the accessor keyword! icmw @observable. E.g. @observable accessor x = y,

Remaining:

Note: I couldn't push to the original repo, so further changes are tracked in #3790

@mweststrate
Copy link
Member

Branch has been merged through #3790, will announce future on Monday!

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.