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
[Fizz] Implement Component Stacks in DEV for warnings #21610
Conversation
Comparing: 44cdfd6...3d2a1ab Critical size changesIncludes critical production bundles, as well as any change greater than 2%:
Significant size changesIncludes any change greater than 0.2%: Expand to show
|
} | ||
function popComponentStackInDEV(task: Task): void { | ||
if (__DEV__) { | ||
invariant( |
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.
Dev invariant. Meh?
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 rationalized it because it would be a React bug if it ever happened, so it shouldn't happen. But yea it shouldn't happen conditionally even then. I'll change it.
}; | ||
}: any); | ||
if (__DEV__) { | ||
task.componentStack = currentTaskInDEV ? task.componentStack : null; |
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.
Why do you check currentTaskInDEV
before reading from task
?
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 looks like a mistake. You're assigning task.componentStack = task.componentStack
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.
Oops. Yea. Looks like I should add a test that tests component stacks when there's a suspended boundary inbetween.
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 we might need to add something similar to flight server renderer, for DevTools
The Flight server renderer is more complicated because it uses JSON.stringify so we don't have access to what happens on the stack. We'd have to reimplement that for DEV or perhaps which technique in both PROD/DEV. There are context related reasons we might want to switch implementation away from JSON.stringify for that reason. |
Right 😬 but we will need something similar for DevTools. Right now, Flight server doesn't track either owner or parent. |
This uses a reverse linked list in DEV-only to keep track of where we're currently executing.
This makes it more explicit which stack we pass in to be retained by the task.
); | ||
} | ||
|
||
// We can't use the toErrorDev helper here because this is an async act. |
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 one is fun. We can probably port it to make it work with async functions too.
Summary: - **[0eea57724](facebook/react@0eea57724 )**: Fix typo in comment (accumlated → accumulated) ([#21637](facebook/react#21637)) //<ithinker5>// - **[0706162ba](facebook/react@0706162ba )**: Fix typo in comment (environement → environment) ([#21635](facebook/react#21635)) //<niexq>// - **[9d17b562b](facebook/react@9d17b562b )**: Fix typo in comment (satsify → satisfy) ([#21629](facebook/react#21629)) //<niexq>// - **[b610fec00](facebook/react@b610fec00 )**: fix comments: expiration time -> lanes ([#21551](facebook/react#21551)) //<Shannon Feng>// - **[cc4d24ab0](facebook/react@cc4d24ab0 )**: [Fizz] Always call flush() if it exists ([#21625](facebook/react#21625)) //<Dan Abramov>// - **[e0d9b2899](facebook/react@e0d9b2899 )**: [Fizz] Minor Fixes for Warning Parity ([#21618](facebook/react#21618)) //<Sebastian Markbåge>// - **[1b7b3592f](facebook/react@1b7b3592f )**: [Fizz] Implement Component Stacks in DEV for warnings ([#21610](facebook/react#21610)) //<Sebastian Markbåge>// - **[39f007489](facebook/react@39f007489 )**: Make enableSuspenseLayoutEffectSemantics static for www ([#21617](facebook/react#21617)) //<Brian Vaughn>// - **[8f3794276](facebook/react@8f3794276 )**: Prepare semver (`latest`) releases in CI ([#21615](facebook/react#21615)) //<Andrew Clark>// - **[8b4201535](facebook/react@8b4201535 )**: Devtools: add feature to trigger an error boundary ([#21583](facebook/react#21583)) //<Bao Pham>// - **[154a8cf32](facebook/react@154a8cf32 )**: Fix reference to wrong variable //<Andrew Clark>// - **[6736a38b9](facebook/react@6736a38b9 )**: Add single source of truth for package versions ([#21608](facebook/react#21608)) //<Andrew Clark>// - **[86715efa2](facebook/react@86715efa2 )**: Resolve the true entry point during tests ([#21505](facebook/react#21505)) //<Sebastian Markbåge>// - **[a8a4742f1](facebook/react@a8a4742f1 )**: Convert ES6/TypeScript/CoffeeScript Tests to createRoot + act ([#21598](facebook/react#21598)) //<Sebastian Markbåge>// - **[1d3558965](facebook/react@1d3558965 )**: Disable deferRenderPhaseUpdateToNextBatch by default ([#21605](facebook/react#21605)) //<Sebastian Markbåge>// - **[a8964649b](facebook/react@a8964649b )**: Delete an unused field ([#21415](facebook/react#21415)) //<okmttdhr>// - **[76f85b3e5](facebook/react@76f85b3e5 )**: Expose Fizz in stable builds ([#21602](facebook/react#21602)) //<Dan Abramov>// - **[e16d61c30](facebook/react@e16d61c30 )**: [Offscreen] Mount/unmount layout effects ([#21386](facebook/react#21386)) //<Andrew Clark>// - **[63091939b](facebook/react@63091939b )**: OSS feature flag updates ([#21597](facebook/react#21597)) //<Brian Vaughn>// - **[efbd69b27](facebook/react@efbd69b27 )**: Define global __WWW__ = true flag during www tests ([#21504](facebook/react#21504)) //<Sebastian Markbåge>// - **[28625c6f4](facebook/react@28625c6f4 )**: Disable strict effects for legacy roots (again) ([#21591](facebook/react#21591)) //<Brian Vaughn>// - **[3c2341416](facebook/react@3c2341416 )**: Update jest to v26 ([#21574](facebook/react#21574)) //<Sebastian Silbermann>// - **[0d493dcda](facebook/react@0d493dcda )**: Removed _debugID field from Fiber - Issue #21558 ([#21570](facebook/react#21570)) //<Pulkit Sharma>// - **[7841d0695](facebook/react@7841d0695 )**: Enable the updater-tracking feature flag in more builds ([#21567](facebook/react#21567)) //<Brian Vaughn>// - **[6405efc36](facebook/react@6405efc36 )**: Enabled Profiling feature flags for OSS release ([#21565](facebook/react#21565)) //<Brian Vaughn>// Changelog: [General][Changed] - React Native sync for revisions 2d8d133...0eea577 jest_e2e[run_all_tests] Reviewed By: bvaughn Differential Revision: D28932083 fbshipit-source-id: 012c1bfb857ed59d7283334d633f1cce8ec50360
* Implement component stacks This uses a reverse linked list in DEV-only to keep track of where we're currently executing. * Fix bug that wasn't picking up the right stack at suspended boundaries This makes it more explicit which stack we pass in to be retained by the task.
This uses a reverse linked list in DEV-only to keep track of where we're currently executing. It works similar to context in that it saves these on the running task.
In addition to this we need access to the current task to extract it. We could keep it only the "current component stack" but we still need to be able to stash it on the task occasionally.
This causes a bit of an awkwardness where current task is available and also the task is passed as an argument to all current functions.
Note that I wasn't planning on using this for production stacks. We don't invoke error boundaries anyway but we could pass stacks to the global callback. But this seems a bit heavy just for that. A variant of this would be to use the plain stack but that doesn't carry along the stack between tasks. A compromise could be to only collect the stack on the current running stack. This is effectively what happens with Promises in production since async boundaries aren't tracked there.