Commit Graph

90 Commits

Author SHA1 Message Date
Brian Vaughn
22ab39be68 DevTools console patching should handle Symbols without erroring (#21368) 2021-04-27 16:36:20 -04:00
Brian Vaughn
fc33f12bde Remove unstable scheduler/tracing API (#20037) 2021-04-26 19:16:18 -04:00
Sebastian Silbermann
84b9162cbe Use toMatchInlineSnapshot for dehydrated values (#20618) 2021-04-26 12:30:34 -04:00
Andrew Clark
a155860018 Fix: Don't flush discrete at end of batchedUpdates (#21229)
The outermost `batchedUpdates` call flushes pending sync updates at the
end. This was intended for legacy sync mode, but it also happens to
flush discrete updates in concurrent mode.

Instead, we should only flush sync updates at the end of
`batchedUpdates` for legacy roots. Discrete sync updates can wait to
flush in the microtask.

`discreteUpdates` has the same issue, which is how I originally noticed
this, but I'll change that one in a separate commit since it requires
updating a few (no longer relevant) internal tests.
2021-04-21 09:32:09 -07:00
Brian Vaughn
bdc23c3dba DevTools shows which fibers scheduled the current update (#21171) 2021-04-09 10:35:06 -04:00
Brian Vaughn
b38ac13f94 DevTools: Add post-commit hook (#21183)
I recently added UI for the Profiler's commit and post-commit durations to the DevTools, but I made two pretty silly oversights:

    1. I used the commit hook (called after mutation+layout effects) to read both the layout and passive effect durations. This is silly because passive effects may not have flushed yet git at this point.
    2. I didn't reset the values on the HostRoot node, so they accumulated with each commit.

    This commitR addresses both issues:

    1. First it adds a new DevTools hook, onPostCommitRoot*, to be called after passive effects get flushed. This gives DevTools the opportunity to read passive effect durations (if the build of React being profiled supports it).
    2. Second the work loop resets these durations (on the HostRoot) after calling the post-commit hook so address the accumulation problem.
    I've also added a unit test to guard against this regressing in the future.

    * Doing this in flushPassiveEffectsImpl seemed simplest, since there are so many places we flush passive effects. Is there any potential problem with this though?
2021-04-08 22:04:51 -04:00
Sebastian Silbermann
1214b302e1 test: Fix "couldn't locate all inline snapshots" (#21205) 2021-04-08 11:18:13 -04:00
Brian Vaughn
bf11788bf0 DevTools Profiler: Add commit and post-commit durations to UI (#20984) 2021-03-17 12:27:37 -04:00
Brian Vaughn
e7d2a558ad DevTools flushes updated passive warning/error info after delay (#20931)
* DevTools flushes updated passive warning/error info after delay
Previously this information was not flushed until the next commit, but this provides a worse user experience if the next commit is really delayed. Instead, the backend now flushes only the warning/error counts after a delay. As a safety, if there are already any pending operations in the queue, we bail.

Co-authored-by: eps1lon <silbermann.sebastian@gmail.com>
2021-03-08 11:33:14 -05:00
Brian Vaughn
cfd8c1bd43 DevTools: Restore inspect-element bridge optimizations (#20789)
* Restore inspect-element bridge optimizations

When the new Suspense cache was integrated (so that startTransition could be used) I removed a couple of optimizations between the backend and frontend that reduced bridge traffic when e.g. dehydrated paths were inspected for elements that had not rendered since previously inspected. This commit re-adds those optimizations as well as an additional test with a bug fix that I noticed while reading the backend code.

There are two remaining TODO items as of this commit:
- Make inspected element edits and deletes also use transition API
- Don't over-eagerly refresh the cache in our ping-for-updates handler

I will addres both in subsequent commits.

* Poll for update only refreshes cache when there's an update

* Added inline comment
2021-02-22 14:04:20 -05:00
Brian Vaughn
3e0bdbefa3 DevTools: Patch console methods even when only show-inline-warnings/errors enabled (#20688) 2021-02-02 10:19:53 -05:00
Brian Vaughn
6d94017c42 DevTools: Make it easier to write tests for inspected elements (#20655)
And also add a few tests for  which also cover a recent bugfix that just landed
2021-01-25 14:58:19 -05:00
ChenLei
ba9582da27 [devtools] Fix can't expand prop value in some scenario (#20534)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2021-01-19 10:26:52 -05:00
Brian Vaughn
af16f755dc Update DevTools to use getCacheForType API (#20548)
DevTools was built with a fork of an early idea for how Suspense cache might work. This idea is incompatible with newer APIs like `useTransition` which unfortunately prevented me from making certain UX improvements. This PR swaps out the primary usage of this cache (there are a few) in favor of the newer `unstable_getCacheForType` and `unstable_useCacheRefresh` APIs. We can go back and update the others in follow up PRs.

### Messaging changes

I've refactored the way the frontend loads component props/state/etc to hopefully make it better match the Suspense+cache model. Doing this gave up some of the small optimizations I'd added but hopefully the actual performance impact of that is minor and the overall ergonomic improvements of working with the cache API make this worth it.

The backend no longer remembers inspected paths. Instead, the frontend sends them every time and the backend sends a response with those paths. I've also added a new "force" parameter that the frontend can use to tell the backend to send a response even if the component hasn't rendered since the last time it asked. (This is used to get data for newly inspected paths.)

_Initial inspection..._
```
front |                                                      | back
      | -- "inspect" (id:1, paths:[], force:true) ---------> |
      | <------------------------ "inspected" (full-data) -- |
```
_1 second passes with no updates..._
```
      | -- "inspect" (id:1, paths:[], force:false) --------> |
      | <------------------------ "inspected" (no-change) -- |
```
_User clicks to expand a path, aka hydrate..._
```
      | -- "inspect" (id:1, paths:['foo'], force:true) ----> |
      | <------------------------ "inspected" (full-data) -- |
```
_1 second passes during which there is an update..._
```
      | -- "inspect" (id:1, paths:['foo'], force:false) ---> |
      | <----------------- "inspectedElement" (full-data) -- |
```

### Clear errors/warnings transition
Previously this meant there would be a delay after clicking the "clear" button. The UX after this change is much improved.

### Hydrating paths transition
I also added a transition to hydration (expanding "dehyrated" paths).

### Better error boundaries
I also added a lower-level error boundary in case the new suspense operation ever failed. It provides a better "retry" mechanism (select a new element) so DevTools doesn't become entirely useful. Here I'm intentionally causing an error every time I select an element.

### Improved snapshot tests
I also migrated several of the existing snapshot tests to use inline snapshots and added a new serializer for dehydrated props. Inline snapshots are easier to verify and maintain and the new serializer means dehydrated props will be formatted in a way that makes sense rather than being empty (in external snapshots) or super verbose (default inline snapshot format).
2021-01-19 09:51:32 -05:00
Brian Vaughn
6630c2de2a Add rudimentary support for Cache to DevTools (#20458) 2021-01-04 09:32:03 -05:00
Brian Vaughn
50393dc3a0 React Native fixes for new inline errors feature (#20502) 2020-12-22 13:58:47 -05:00
Sebastian Silbermann
09a2c363a5 Expose DEV-mode warnings in devtools UI (#20463)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-12-22 11:09:29 -05:00
Brian Vaughn
4053c76b7d Add more DevTools tests for React.Lazy (#20380) 2020-12-06 09:10:15 -05:00
Brian Vaughn
75726fadfd DevTools fix props editing for host components (#20055) 2020-10-19 15:21:41 -04:00
oltrep
f668b6c351 Bump to latest eslint-config-fbjs (#20029)
* bump package to latest

* update files to respect lint

* disable object-type-delimiter rule to work with prettier

* disable rule to let flow check pass
2020-10-16 16:06:08 +01:00
IDrissAitHafid
2eb3181eb4 fixed unfound node error when Suspense is filtered (#20019)
* fixed unfound node error when Suspense is filtered

* added a test for filtered Suspense node
2020-10-15 14:45:23 -04:00
Brian Vaughn
f75f8b48a2 DevTools always overrides the dispatcher when shallow rendering (#20011)
This is done so that any effects scheduled by the shallow render are thrown away.

Unlike the code this was forked from (in ReactComponentStackFrame) DevTools should override the dispatcher even when DevTools is compiled in production mode, because the app itself may be in development mode and log errors/warnings.
2020-10-14 13:19:47 -04:00
IDrissAitHafid
e614e69657 handled a missing suspense fiber when suspense is filtered on the profiler (#19987)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-10-13 13:38:58 -04:00
Todor Totev
92c7e49895 Don't consumer iterators while inspecting (#19831)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-09-22 14:23:20 -04:00
Brian Vaughn
50d9451f32 Improve DevTools editing interface (#19774)
* Improve DevTools editing interface

This commit adds the ability to rename or delete keys in the props/state/hooks/context editor and adds tests to cover this functionality. DevTools will degrade gracefully for older versions of React that do not inject the new reconciler rename* or delete* methods.

Specifically, this commit includes the following changes:
* Adds unit tests (for modern and legacy renderers) to cover overriding props, renaming keys, and deleting keys.
* Refactor backend override methods to reduce redundant Bridge/Agent listeners and methods.
* Inject new (DEV-only) methods from reconciler into DevTools to rename and delete paths.
* Refactor 'inspected element' UI components to improve readability.
* Improve auto-size input to better mimic Chrome's Style editor panel. (See this Code Sandbox for a proof of concept.)

It also contains the following code cleanup:
* Additional unit tests have been added for modifying values as well as renaming or deleting paths.
* Four new DEV-only methods have been added to the reconciler to be injected into the DevTools hook: overrideHookStateDeletePath, overrideHookStateRenamePath, overridePropsDeletePath, and overridePropsRenamePath. (DevTools will degrade gracefully for older renderers without these methods.)
* I also took this as an opportunity to refactor some of the existing code in a few places:
  * Rather than the backend implementing separate methods for editing props, state, hooks, and context– there are now three methods: deletePath, renamePath, and overrideValueAtPath that accept a type argument to differentiate between props, state, context, or hooks.
  * The various UI components for the DevTools frontend have been refactored to remove some unnecessary repetition.

This commit also adds temporary support for override* commands with mismatched backend/frontend versions:
* Add message forwarding for older backend methods (overrideContext, overrideHookState, overrideProps, and overrideState) to the new overrideValueAtPath method. This was done in both the frontend Bridge (for newer frontends passing messages to older embedded backends) and in the backend Agent (for older frontends passing messages to newer backends). We do this because React Native embeds the React DevTools backend, but cannot control which version of the frontend users use.
* Additional unit tests have been added as well to cover the older frontend to newer backend case. Our DevTools test infra does not make it easy to write tests for the other way around.
2020-09-18 11:07:18 -04:00
6h057
917cb01a58 React DevTools: Show symbols used as keys in state (#19786)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-09-14 09:55:19 -04:00
Andrew Clark
d17086c7c8 Decouple public, internal act implementation (#19745)
In the next major release, we intend to drop support for using the `act`
testing helper in production. (It already fires a warning.) The
rationale is that, in order for `act` to work, you must either mock the
testing environment or add extra logic at runtime. Mocking the testing
environment isn't ideal because it requires extra set up for the user.
Extra logic at runtime is fine only in development mode — we don't want
to slow down the production builds.

Since most people only run their tests in development mode, dropping
support for production should be fine; if there's demand, we can add it
back later using a special testing build that is identical to the
production build except for the additional testing logic.

One blocker for removing production support is that we currently use
`act` to test React itself. We must test React in both development and
production modes.

So, the solution is to fork `act` into separate public and
internal implementations:

- *public implementation of `act`* – exposed to users, only works in
  development mode, uses special runtime logic, does not support partial
  rendering
- *internal implementation of `act`* – private, works in both
  development and productionm modes, only used by the React Core test
  suite, uses no special runtime logic, supports partial rendering (i.e.
  `toFlushAndYieldThrough`)

The internal implementation should mostly match the public
implementation's behavior, but since it's a private API, it doesn't have
to match exactly. It works by mocking the test environment: it uses a
mock build of Scheduler to flush rendering tasks, and Jest's mock timers
to flush Suspense placeholders.

---

In this first commit, I've added the internal forks of `act` and
migrated our tests to use them. The public `act` implementation is
unaffected for now; I will leave refactoring/clean-up for a later step.
2020-09-08 08:11:45 -07:00
Brian Vaughn
98dba66ee1 Add ⎇ + arrow key navigation to DevTools (#19741)
⎇ + left/right navigates between owners (similar to owners tree) and ⎇ + up/down navigations between siblings.
2020-09-01 20:03:44 -04:00
Ben Pernick
60ba723bf7 Add SuspenseList to devTools (#19684)
* ensure getDisplayName is only called on functions

* add SuspenseList to Dev tools element names

* Add SuspenseList and pass tests

* Import SuspenseList directly

* run prettier

* Refactor tests to use real components

* run linter
2020-08-26 18:04:43 +01:00
Pascal Fong Kye
b6e1d08604 DevTools bug fix: Proxied methods should be safely dehydrated for display 2020-08-12 12:15:53 -04:00
Brian Vaughn
0c52e24cb6 Support inner component _debugOwner in memo (#19556)
* Support inner component _debugOwner in memo

* test with devtool context

* remove memo test

* Merged master; tweaked test and snapshot

* Pass owner to createFiber fn when creating a memo component.

Co-authored-by: Theodore Han <tqhan317@gmail.com>
2020-08-10 10:49:10 -04:00
Brian Vaughn
a89854bc93 Fix Suspense-wrapping heuristic (and bump version numbers) (#19373)
* Fixed suspense wrapping heuristic

* Bump package numbers 16.13.1 -> 17.0.0-alpha.0 to fix DevTools Suspense heuristic
2020-07-15 12:25:27 -04:00
Brian Vaughn
fbc6386369 Fix DevTools handling of empty Suspense tag for legacy renderer versions (#19337) 2020-07-13 16:21:56 -04:00
Brian Vaughn
d5d659062d Updated DevTools test snapshots 2020-07-10 13:06:50 -04:00
Andrew Clark
6ba25b96df Bugfix: Legacy Mode + DevTools "force fallback" (#19164)
DevTools has a feature to force a Suspense boundary to show a fallback.
This feature causes us to skip the first render pass (where we render
the primary children) and go straight to rendering the fallback.

There's a Legacy Mode-only codepath that failed to take this scenario
into account, instead assuming that whenever a fallback is being
rendered, it was preceded by an attempt to render the primary children.

SuspenseList can also cause us to skip the first pass, but the relevant
branch is Legacy Mode-only, and SuspenseList is not supported in
Legacy Mode.

Fixes a test that I had temporarily disabled when upstreaming the Lanes
implementation in #19108.
2020-06-19 11:06:42 -07:00
Ricky
30b47103d4 Fix spelling errors and typos (#19138) 2020-06-15 19:59:44 -04:00
Andrew Clark
8f05f2bd6d Land Lanes implementation in old fork (#19108)
* Add autofix to cross-fork lint rule

* replace-fork: Replaces old fork contents with new

For each file in the new fork, copies the contents into the
corresponding file of the old fork, replacing what was already there.

In contrast to merge-fork, which performs a three-way merge.

* Replace old fork contents with new fork

First I ran  `yarn replace-fork`.

Then I ran `yarn lint` with autofix enabled. There's currently no way to
do that from the command line (we should fix that), so I had to edit the
lint script file.

* Manual fix-ups

Removes dead branches, removes prefixes from internal fields.  Stuff
like that.

* Fix DevTools tests

DevTools tests only run against the old fork, which is why I didn't
catch these earlier.

There is one test that is still failing. I'm fairly certain it's related
to the layout of the Suspense fiber: we no longer conditionally wrap the
primary children. They are always wrapped in an extra fiber.

Since this has been running in www for weeks without major issues, I'll
defer fixing the remaining test to a follow up.
2020-06-11 20:05:15 -07:00
Brian Vaughn
2efe63d99c DevTools: Add break-on-warn feature (#19048)
This commit adds a new tab to the Settings modal: Debugging

This new tab has the append component stacks feature and a new one: break on warn

This new feature adds a debugger statement into the console override
2020-05-29 14:34:43 -07:00
Nick Reiley
dd2e36df33 Profiler: Skip reading element for imported data (#18913)
* skip reading element for imported data

* rename nodes & enable store lookup for components tab

* replace names

* Added some more test coverage; reverted rename

Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-05-15 10:38:01 -07:00
Nick Reiley
7c080902ef [DevTools] Improve HOC search UX (#18802)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
2020-05-15 10:37:34 -07:00
Brian Vaughn
69e732ac9d Disable Profiler commit filtering (#18862)
* Disable Profiler commit filtering

We used to filter "empty" DevTools commits, but it was error prone (see #18798). A commit may appear to be empty (no actual durations) because of component filters, but filtering these empty commits causes interaction commit indices to be off by N. This not only corrupts the resulting data, but also potentially causes runtime errors.

For that matter, hiding "empty" commits might cause confusion too. A commit *did happen* even if none of the components the Profiler is showing were involved.

* Restart flaky CI
2020-05-07 17:07:20 -07:00
Andrew Clark
fe7163e73d Add unstable prefix to experimental APIs (#18825)
We've been shipping unprefixed experimental APIs (like `createRoot` and
`useTransition`) to the Experimental release channel, with the rationale
that because these APIs do not appear in any stable release, we're free
to change or remove them later without breaking any downstream projects.

What we didn't consider is that downstream projects might be tempted to
use feature detection:

```js
const useTransition = React.useTransition || fallbackUseTransition;
```

This pattern assumes that the version of `useTransition` that exists in
the Experimental channel today has the same API contract as the final
`useTransition` API that we'll eventually ship to stable.

To discourage feature detection, I've added an `unstable_` prefix to
all of our unstable APIs.

The Facebook builds still have the unprefixed APIs, though. We will
continue to support those; if we make any breaking changes, we'll
migrate the internal callers like we usually do. To make testing easier,
I added the `unstable_`-prefixed APIs to the www builds, too. That way
our tests can always use the prefixed ones without gating on the
release channel.
2020-05-04 22:25:41 -07:00
Brian Vaughn
b9fc3d8d59 DevTools temporarily disable prepareStackTrace before creating custom component stacks (#18717) 2020-04-23 09:02:42 -07:00
Brian Vaughn
36cab2720a DevTools: Improved "native" component stacks (#18656)
* DevTools console override handles new component stack format

DevTools does not attempt to mimic the default browser console format for its component stacks but it does properly detect the new format for Chrome, Firefox, and Safari.
2020-04-21 11:46:11 -07:00
Andrew Clark
bec7599067 Migrate conditional tests to gate pragma (#18585)
* Migrate conditional tests to gate pragma

I searched through the codebase for this pattern:

```js
describe('test suite', () => {
  if (!__EXPERIMENTAL__) { // or some other condition
    test("empty test so Jest doesn't complain", () => {});
    return;
  }

  // Unless we're in experimental mode, none of the tests in this block
  // will run.
})
```

and converted them to the `@gate` pragma instead.

The reason this pattern isn't preferred is because you end up disabling
more tests than you need to.

* Add flag for www release channels

Using a heuristic where I check a flag that is known to only be enabled
in www. I left a TODO to instead set the release channel explicitly in
each test config.
2020-04-13 14:45:52 -07:00
Sebastian Markbåge
98d410f500 Build Component Stacks from Native Stack Frames (#18561)
* Implement component stack extraction hack

* Normalize errors in tests

This drops the requirement to include owner to pass the test.

* Special case tests

* Add destructuring to force toObject which throws before the side-effects

This ensures that we don't double call yieldValue or advanceTime in tests.

Ideally we could use empty destructuring but ES lint doesn't like it.

* Cache the result in DEV

In DEV it's somewhat likely that we'll see many logs that add component
stacks. This could be slow so we cache the results of previous components.

* Fixture

* Add Reflect to lint

* Log if out of range.

* Fix special case when the function call throws in V8

In V8 we need to ignore the first line. Normally we would never get there
because the stacks would differ before that, but the stacks are the same if
we end up throwing at the same place as the control.
2020-04-10 13:32:12 -07:00
Sebastian Markbåge
4169420198 Refactor Component Stack Traces (#18495)
* Add feature flag

* Split stack from current fiber

You can get stack from any fiber, not just current.

* Refactor description of component frames

These should use fiber tags for switching. This also puts the relevant code
behind DEV flags.

* We no longer expose StrictMode in component stacks

They're not super useful and will go away later anyway.

* Update tests

Context is no longer part of SSR stacks. This was already the case on the
client.

forwardRef no longer is wrapped on the stack. It's still in getComponentName
but it's probably just noise in stacks. Eventually we'll remove the wrapper
so it'll go away anyway. If we use native stack frames they won't have this
extra wrapper.

It also doesn't pick up displayName from the outer wrapper. We could maybe
transfer it but this will also be fixed by removing the wrapper.

* Forward displayName onto the inner function for forwardRef and memo in DEV

This allows them to show up in stack traces.

I'm not doing this for lazy because lazy is supposed to be called on the
consuming side so you shouldn't assign it a name on that end. Especially
not one that mutates the inner.

* Use multiple instances of the fake component

We mutate the inner component for its name so we need multiple copies.
2020-04-06 15:43:39 -07:00
Sebastian Markbåge
3e94bce765 Enable prefer-const lint rules (#18451)
* Enable prefer-const rule

Stylistically I don't like this but Closure Compiler takes advantage of
this information.

* Auto-fix lints

* Manually fix the remaining callsites
2020-04-01 12:35:52 -07:00
Brian Vaughn
bd5781962a Inlined DevTools event emitter impl (#18378)
DevTools previously used the NPM events package for dispatching events. This package has an unfortunate flaw though- if a listener throws during event dispatch, no subsequent listeners are called. I've replaced that event dispatcher with my own implementation that ensures all listeners are called before it re-throws an error.

This commit replaces that event emitter with a custom implementation that calls all listeners before re-throwing an error.
2020-03-25 10:26:40 -07:00
Sebastian Silbermann
756e1ea5d4 fix(react-devtools-shared): useDebugValue with complex types (#18070)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
2020-03-17 13:57:01 -07:00