Commit Graph
13703 Commits
Author SHA1 Message Date
Sebastian MarkbågeandGitHub bbaee487c0 Add Node ESM Loader and Register Entrypoints (#20274)
* Add Node ESM loader build

This adds a loader build as a first-class export. This will grow in
complexity so it deserves its own module.

* Add Node CommonJS regiter build

This adds a build as a first-class export for legacy CommonJS registration
in Node.js. This will grow in complexity so it deserves its own module.

* Simplify fixture a bit to easier show usage with or without esm

* Bump es version

We leave async function in here which are newer than ES2015.
2020-11-16 23:46:27 -05:00
Andrew ClarkandGitHub d56c282c1d findDOMNode: Remove return pointer mutation (#20272)
The last step of the `findDOMNode` algorithm is a search of the
current tree.

When descending into a child node, it mutates `child.return` so that it
points to the current fiber pair, instead of a work-in-progress. This
can cause bugs if `findDOMNode` is called at the wrong time, like in
an interleaved event.

For this reason (among others), you're not suppposed to use
`findDOMNode` in Concurrent Mode. However, we still have some internal
uses that we haven't migrated.

To reduce the potential for bugs, I've removed the `.return` pointer
assignment in favor of recursion.
2020-11-16 15:09:53 -08:00
Andrew ClarkandGitHub 5875f1733b Add separate ChildDeletion flag (#20264)
In the old, effect list implementation, the Deletion flag is is set on
each deleted fiber.

In the new, subtreeTag implementation, the Deletion flag is set on the
parent of each deleted fiber, and the deleted fibers themselves are
pushed to the `deletions` array.

To better distinguish between these two uses, I've added a separate
ChildDeletion flag. That way we can, if desired, maintain both
implementations simultaneously, as we bisect to find the performance
regression that we're currently investigating.
2020-11-16 09:13:39 -06:00
Andrew ClarkandGitHub a633f5a621 Reset new fork to old fork (#20254)
* Fix typo

This typo was fixed in the new fork but not the old.

* Reset new fork to old fork

Something in the new fork is causing a topline metrics regression. We're
not sure what it is, so we're going to split it into steps and bisect.

As a first step, this resets the new fork back to the contents of the
old fork. We will land this to confirm that the fork infra itself is
not causing a regression.

* Fix tests: Add `dfsEffectsRefactor` flag

Some of the tests that gated on the effects refactor used the `new`
flag. In order to bisect, we'll need to decompose the new fork changes
into multiple steps.

So I added a hardcoded test flag called `dfsEffectsRefactor` and set it
to false. Will turn back on when we switch back to traversing the
finished tree using DFS and `subtreeTag`.
2020-11-13 11:54:33 -08:00
Brian VaughnandGitHub 794ac7e0e2 Properly reset Profiler nested-update flag (#20253)
Previously this flag was not being reset correctly if a concurrent update followed a nested (sync) update. This PR fixes the behavior and adds a regression test.
2020-11-13 14:29:06 -05:00
Andrew ClarkandGitHub aff6059a51 Add --reverse option to replace-fork script (#20249)
When enabled, replaces new fork with old fork.

I've done this several times by manually editing the script file, so
seems useful enough to add an option.
2020-11-13 11:09:02 -08:00
Andrew ClarkandGitHub 6e25817cb3 Autofix imports when running replace-fork (#20251)
* Pass extra CLI args through to ESLint

These now work:

```
yarn run lint --fix
yarn run linc --fix
```

* Autofix imports when running replace-fork

We have a custom ESLint rule that can autofix cross-fork imports.

Usually, after running the `replace-fork` script, you need to run
`yarn lint --fix` to fix the imports.

This combines the two steps into one.
2020-11-13 11:01:25 -08:00
Andrew ClarkandGitHub 9fa2564b0d Pass extra CLI args through to ESLint (#20250)
These now work:

```
yarn run lint --fix
yarn run linc --fix
```
2020-11-13 11:00:45 -08:00
Andrew ClarkandGitHub b86daa68f1 Check for deletions in hadNoMutationsEffects (#20252)
When detecting if a host tree was changed, we must check for deletions
in addition to mounts and updates.
2020-11-13 10:45:46 -08:00
Andrew ClarkandGitHub 168d054cd5 Add new effect fields to old fork, and vice versa (#20246)
* Add new effect fields to old fork

So that when comparing relative performance, we don't penalize the new
fork for using more memory.

* Add firstEffect, et al fields to new fork

We need to bisect the changes to the recent commit phase refactor. To
do this, we'll need to add back the effect list temporarily.

This only adds them to the Fiber type so that the memory is the same
as the old fork.
2020-11-13 08:09:48 -08:00
090116b9a6 Remove cycle between ReactFiberHooks and ReactInternalTypes (#20242)
Co-authored-by: Paul Doyle <[email protected]>
2020-11-13 09:18:24 -05:00
Sebastian MarkbågeandGitHub 6a74c0554b Add Node ESM build option (#20243)
This allows exporting ESM modules for the Webpack plugin. This is necessary
for making a resolver plugin. We could probably make the whole plugin
use ESM instead of CJS ES2015.
2020-11-13 05:57:45 -08:00
Andrew ClarkandGitHub d1acaf7675 Remove noinline directives from new commit phase (#20241)
My theory for too much inlining contributing to overall stack size is
likely flawed, because Closure reuses variables within a function to
optimize registers.

Even if my theory were correct, the impact would be minimal anyway
because the recursive implementation of the commit phase traversals is
behind a disabled feature flag.

Going to revert this. We can maybe test the impact once we land the
commit phase changes. In the meantime, I'd prefer to eliminate this
delta from the new fork.
2020-11-12 10:21:56 -08:00
Sebastian MarkbågeandGitHub f8a4540f28 Support ESM module loaders in Flight fixture (#20229)
This lets the Flight fixture run as "type": "module" or "commonjs".

Experimental loaders can be used similar to require.extensions to do the
transpilation and replacement of .client.js references.
2020-11-12 08:11:05 -08:00
Brian VaughnandGitHub 0334e0c5cf Scheduling profiler tweaks (#20215) 2020-11-12 09:47:04 -05:00
Brian VaughnandGitHub 5136644dd2 Add Profiler callback when nested updates are scheduled (#20211)
This callback accepts the no parameters (except for the current interactions). Users of this hook can inspect the call stack to access and log the source location of the component.
2020-11-12 09:31:27 -05:00
Brian Vaughn 5fef98a1c0 DevTools 4.9.0 -> 4.10.0 2020-11-12 09:07:10 -05:00
Dan Abramov 029e8e1e7d [email protected] 2020-11-12 00:36:00 +00:00
Billy JanitschandGitHub decac97b73 Widen peer dependency range of use-subscription (#20225) 2020-11-12 00:30:19 +00:00
Andrew ClarkandGitHub f0b93edd79 Add warning if return pointer is inconsistent (#20219)
Bugs caused by inconsistent return pointers are tricky to diagnose
because the source of the error is often in a different part of the
codebase from the actual mistake. For example, you might forget to set a
return pointer during the render phase, which later causes a crash in
the commit phase.

This adds a dev-only invariant to the commit phase to check for
inconsistencies. With this in place, we'll hopefully catch return
pointer errors quickly during local development, when we have the most
context for what might have caused it.
2020-11-11 09:06:37 -06:00
284bfe0ce9 Improved dev experience when DevTools hook is disabled (#20208)
Co-authored-by: Brian Vaughn <[email protected]>
2020-11-11 09:36:51 -05:00
Sebastian MarkbågeandGitHub 692f3ae765 Perform hasOwnProperty check in Relay Flight (#20220)
We simulate JSON.stringify in this loop so we should do a has own check.
Otherwise we'll include things like constructor properties.

This will actually make things throw less even when it should.
2020-11-10 19:59:46 -08:00
Sebastian MarkbågeandGitHub 200c81e20a Dedupe module id generation (#20172) 2020-11-10 19:58:58 -08:00
Sebastian MarkbågeandGitHub 9c34e88eaa [Flight] Encode Symbols as special rows that can be referenced by models … (#20171)
* Encode Symbols as special rows that can be referenced by models

If a symbol was extracted from Symbol.for(...) then we can reliably
recreate the same symbol on the client.

S123:"react.suspense"
M456:{mySymbol: '$123'}

This doesn't suffer from the XSS problem because you have to write actual
code to create one of these symbols. That problem is only a problem because
values pass through common other usages of JSON which are not secure.

Since React encodes its built-ins as symbols, we can now use them as long
as its props are serializable. Like Suspense.

* Refactor resolution to avoid memo hack

Going through createElement isn't quite equivalent for ref and key in props.

* Reuse symbol ids that have already been written earlier in the stream
2020-11-10 19:56:50 -08:00
Sebastian MarkbågeandGitHub fb64faaac9 [Flight] Simplify Relay row protocol (#20168)
* Simplify Relay protocol integration

* Encode Relay rows as tuples instead of objects

This is slightly more compact and more ressembles more closely the encoding
we use for the raw stream protocol.
2020-11-10 19:54:42 -08:00
Sebastian MarkbågeandGitHub d99109b60a Encode throwing server components as lazy throwing references (#20217)
This ensures that if this server component was the child of a client
component that has an error boundary, it doesn't trigger the error until
this gets rendered so it happens as deep as possible.
2020-11-10 16:35:27 -08:00
Sebastian MarkbågeandGitHub e98019e6b8 [Flight] Expand the fixture to use require.extensions (#20209)
* Expand fixture

Use .server convention. /server/index.js should really change too so it can be compiled but for now we treat it as bootstrapping code outside the compiled code.

Move App.server. It's part of the application code rather than the infra.

Add hybrid component used in both server/client and an extra component shared by multiple entry points.

* Use require.extensions to replace .client imports

The simplest server doesn't need AOT compilation. Instead we can just
configure require.extensions. This is probably not the best idea to use
in prod but is enough to show the set up.
2020-11-10 12:48:51 -08:00
Andrew ClarkandGitHub 4e234708b2 Set return pointer when reusing current tree (#20212)
* Do not fix return pointers during commit phase

In the commit phase, we should be able to assume that the `return`
pointers in the just-completed tree are consistent. The render phase
should be responsible for ensuring these are always correct.

I've removed the `return` pointer assignments from the render phase
traversal logic. This isn't all of them, only the ones added recently
during the effects refactor. The other ones have been around longer so
I'll leave those for a later clean up.

This breaks a few SuspenseList tests; I'll fix in the next commit.

* Set return pointer when reusing current tree

We always set the return pointer on freshly cloned, work-in-progress
fibers. However, we were neglecting to set them on trees that are reused
from current.

I fixed this in the same path of the complete phase where we reset the
fiber flags.

This is a code smell because it assumes the commit phase is never
concurrent with the render phase. Our eventual goal is to make fibers a
lock free data structure.

Will address further during refactor to alternate model.
2020-11-10 11:20:04 -08:00
RickyandGitHub 738ca86f5a Add version of scheduler that only swaps MessageChannel for postTask (#20206)
* Fork SchedulerDOM to SchedulerPostTaskOnly

* Swap in postTask for MessageChannel

* Add SchedulerPostTaskOnly-test.js

* Update getCurrentTime

* Gate tests to source

* Prettier
2020-11-10 12:11:46 -05:00
Brian VaughnandGitHub bcdd78869b Add "nested-update" phase to Profiler API (#20163)
Background:
State updates that are scheduled in a layout effect (useLayoutEffect or componentDidMount / componentDidUpdate) get processed synchronously by React before it yields to the browser to paint. This is done so that components can adjust their layout (e.g. position and size a tooltip) without any visible shifting being seen by users. This type of update is often called a "nested update" or a "cascading update".

Because they delay paint, nested updates are considered expensive and should be avoided when possible. For example, effects that do not impact layout (e.g. adding event handlers, logging impressions) can be safely deferred to the passive effect phase by using useEffect instead.

This PR updates the Profiler API to explicitly flag nested updates so they can be monitored for and avoided when possible.

Implementation:
I considered a few approaches for this.

Add a new callback (e.g. onNestedUpdateScheduled) to the Profiler that gets called when a nested updates gets scheduled.
Add an additional boolean parameter to the end of existing callbacks (e.g. wasNestedUpdate).
Update the phase param to add an additional variant: "mount", "update", or "nested-update" (new).
I think the third option makes for the best API so that's what I've implemented in this PR.

Because the Profiler API is stable, this change will need to remain behind a feature flag until v18. I've turned the feature flag on for Facebook builds though after confirming that Web Speed does not currently make use of the phase parameter.

Quirks:
One quirk about the implementation I've chosen is that errors thrown during the layout phase are also reported as nested updates. I believe this is appropriate since these errors get processed synchronously and block paint. Errors thrown during render or from within passive effects are not affected by this change.
2020-11-10 09:40:30 -05:00
Sean KeenanandGitHub 70b1b211cd react-devtools-inline: Remove css-sourcemap's when bundling for dist (#20170) 2020-11-10 08:47:39 -05:00
RickyandGitHub 5d04065855 Fix path for SchedulerFeatureFlags (#20200) 2020-11-09 11:22:59 -05:00
Brian VaughnandGitHub a1f7c9a657 (Temporarily) revert unmounting error boundaries changes (#20147)
This reverts commits 367c24ea79 and 7012428b49, although neither revert cleanly since methods have been moved between the work-loop and commit-work files. This commit is a mostly manual effort of undoing the changes.
2020-11-09 10:14:24 -05:00
inokawaandGitHub feded99dad Fix typo (#20188) 2020-11-09 09:17:40 -05:00
Jack WorksandGitHub 531452a7ca fix: useImperativeMethods to useImperativeHandle (#20194) 2020-11-08 19:59:53 +00:00
RickyandGitHub 1e1419105c Add workspaces hash to yarn cache key (#20154)
* Add branch to yarn cache key

* Add checksum check for workspace info

* Fix yaml

* Try moving the command

* How about here

* Just inline it

* i hate it here

* try reverting back

* Add run

* idk

* try inlining the command everywhere

* Create workspace_info.txt when we create the cache

* Delete the timestamp
2020-11-03 15:02:06 -05:00
Deniz SusmanandGitHub 74c9b662d0 typo fix in comment (#20153) 2020-11-03 09:57:56 -05:00
Dan AbramovandGitHub ba7d3b2de3 [Flight Fixture] Server + Client Components (#20150) 2020-11-03 03:00:23 +00:00
Sebastian MarkbågeandGitHub 0440e5c6a1 Add Relay specific React Native build of Flight (#20149)
This adds a new dimension similar to dom-relay. It's different from
"native" which would be Flight for RN without Relay.

This has some copy-pasta that's the same between the two Relay builds but
the key difference will be Metro and we're not quite sure what other
differences there will be yet.
2020-11-02 18:49:48 -08:00
RickyandGitHub 643601f160 Refactor SchedulerHostConfigs (#20025)
* Remove SchedulerHostConfigs

* Fix builds

* Fix forks

* Move SchedulerNoDom check to npm/index.js

* Fix tests

* Add @gate source

* Gate build-only test to build test runs
2020-11-02 12:46:58 -05:00
Sebastian MarkbågeandGitHub c4723c3a8f Remove Blocks (#20138)
* Remove Blocks

* Remove Flight Server Runtime

There's no need for this now that the JSResource is part of the bundler
protocol. Might need something for Webpack plugin specifically later.

* Devtools
2020-10-30 23:03:45 -07:00
Sebastian MarkbågeandGitHub 4a2d0c0875 Serialize pending server components by reference (lazy component) (#20137)
This now means that if a server component suspends, its value becomes a
React.lazy object. I.e. the element that rendered the server component
gets replaced with a lazy node.

As of #19033 lazy objects can be rendered in the node position. This allows
us to suspend at the location of the server component while we're waiting
on its content.

Now server components has the same capabilities as Blocks to progressively
reveal its content.
2020-10-30 17:19:46 -07:00
Sebastian MarkbågeandGitHub e60c511706 Allow values to be encoded by "reference" to a value rather than the value itself (#20136)
These references are currently transformed into React.lazy values. We can use these in
React positions like element type or node position.

This could be expanded to a more general concept like Suspensey Promises, asset references or JSResourceReferences.

For now it's only used in React Element type position.

The purpose of these is to let you suspend deeper in the tree.
2020-10-30 13:02:03 -07:00
Sebastian MarkbågeandGitHub 45118d5f3d Rename (#20134) 2020-10-29 18:58:32 -07:00
Sebastian MarkbågeandGitHub 131c1a2d41 [Flight] Add support for Module References in transport protocol (#20121)
* Refactor Flight to require a module reference to be brand checked

This exposes a host environment (bundler) specific hook to check if an
object is a module reference. This will be used so that they can be passed
directly into Flight without needing additional wrapper objects.

* Emit module references as a special type of value

We already have JSON and errors as special types of "rows". This encodes
module references as a special type of row value. This was always the
intention because it allows those values to be emitted first in the stream
so that as a large models stream down, we can start preloading as early
as possible.

We preload the module when they resolve but we lazily require them as they
are referenced.

* Emit module references where ever they occur

This emits module references where ever they occur. In blocks or even
directly in elements.

* Don't special case the root row

I originally did this so that a simple stream is also just plain JSON.

However, since we might want to emit things like modules before the root
module in the stream, this gets unnecessarily complicated. We could add
this back as a special case if it's the first byte written but meh.

* Update the protocol

* Add test for using a module reference as a client component

* Relax element type check

Since Flight now accepts a module reference as returned by any bundler
system, depending on the renderer running. We need to drastically relax
the check to include all of them. We can add more as we discover them.

* Move flow annotation

Seems like our compiler is not happy with stripping this.

* Some bookkeeping bug

* Can't use the private field to check
2020-10-29 17:57:31 -07:00
Brian VaughnandGitHub 1e7756dd1c Fast Refresh: Don't block DevTools commit hook (#20129)
In some scenarios (either timing dependent, or pre-FR compatible React versions) FR blocked calling the React DevTools commit hook. This PR adds a test and a fix for that.
2020-10-29 13:23:57 -04:00
Brian VaughnandGitHub 234d7d2147 Make DevTools Websocket retry delay configurable (#20107) 2020-10-28 22:08:47 -04:00
Andrew ClarkandGitHub 95b82a0622 Prevent inlining into recursive commit functions (#20105)
Adds a bunch of no-inline directives to commit phase functions to
prevent them from being inlined into one of our recursive algorithms.

The motivation is to minimize the number of variables in the recursive
functions, since each one contributes to the size of the stack frame.

Theoretically, this could help the performance of both the recursive
and non-recursive (iterative) implementations of the commit phase,
since even the iterative implementation sometimes uses the JS stack.
2020-10-27 12:51:34 -07:00
Andrew ClarkandGitHub 0c9ee6c483 Traverse commit phase effects iteratively (#20094)
* Move traversal logic to ReactFiberCommitWork

The current traversal logic is spread between ReactFiberWorkLoop and
ReactFiberCommitWork, and it's a bit awkward, especially when
refactoring. Idk the ideal module structure, so for now I'd rather keep
it all in one file.

* Traverse commit phase effects iteratively

We suspect that using the JS stack to traverse through the tree in the
commit phase is slower than traversing iteratively.

I've kept the recursive implementation behind a flag, both so we have
the option to run an experiment comparing the two, and so we can revert
it easily later if needed.
2020-10-27 12:02:19 -07:00
a9a8781f40 Allow Node 15.x (#20108)
Co-authored-by: Justus Hämäläinen <[email protected]>
2020-10-27 15:16:16 +00:00