* Remove deprecated folder mapping
Node v16 deprecated the use of trailing "/" to define subpath folder
mappings in the "exports" field of package.json.
The recommendation is to explicitly list all our exports. We already do
that for all our public modules. I believe the only reason we have a
wildcard pattern is because our package.json files are also used at
build time (by Rollup) to resolve internal source modules that don't
appear in the final npm artifact.
Changing trailing "/" to "/*" fixes the warnings. See
https://nodejs.org/api/packages.html#subpath-patterns for more info.
Since the wildcard pattern only exists so our build script has access to
internal at build time, I've scoped the wildcard to "/src/*". Because
our public modules are located outside the "src" directory, this means
deep imports of our modules will no longer work: only packages that are
listed in the "exports" field.
The only two affected packages are react-dom and react. We need to be
sure that all our public modules are still reachable. I audited the
exports by comparing the entries to the "files" field in package.json,
which represents a complete list of the files that are included in the
final release artifact.
At some point, we should add an e2e packaging test to prevent
regressions; for now, we should have decent coverage because in CI we
run our Jest test suite against the release artifacts.
* Remove umd from exports
Our expectation is that if you're using the UMD builds, you're not
loading them through a normal module system like require or import.
Instead you're probably copying the files directly or loading them from
a CDN like unpkg.
Alternative to #23254
Our build script has a custom plugin to resolve internal module forks.
Currently, it uses require.resolve to resolve the path to a real file
on disk.
Instead, I've updated all the forked module paths to match their
location on disk, relative to the project root, to remove the need to
resolve them in the build script's runtime.
The main motivation is because require.resolve doesn't work with ESM
modules, but aside from that, hardcoding the relative paths is more
predictable — the Node module resolution algorithm is complicated, and
we don't really need its features for this purpose.
* Use consistent naming for unstable_testing entry point
* Exclude the testing build from non-experimental builds except at FB
* FB builds shouldn't contribute to whether we include the npm files
* Exclude exports fields if we delete the files entry
* Move test to no longer be internal so we can test against the build
* Update the bundle artifact names since they've now changed
* Gate import since it doesn't exist
This indicates that an error has happened before the shell completed and
there's no point in emitting the result of this stream.
This is not quite the same as other fatal errors that can happen even
after streaming as started.
It's also not quite the same as onError before onCompleteShell because
onError can be called for an error inside a Suspense boundary before the
shell completes.
Implement shell error handling in Node SSR fixtures
Instead of hanging indefinitely.
Update Browser Fixture
Expose onErrorShell to the Node build
This API is not Promisified so it's just a separate callback instead.
Promisify the Browser Fizz API
It's now a Promise of a readable stream. The Promise resolves when the
shell completes. If the shell errors, the Promise is rejected.
* Add .browser and .node explicit entry points
This can be useful when the automatic selection doesn't work properly.
* Remove react/index
I'm not sure why I added this in the first place. Perhaps due to how our
builds work somehow.
* Remove build-info.json from files field
This configures the exports field for react-dom.
Notably there are some conditions for the /server entry point where we pick
the export based on environments. Most environments now support Web Streams
which is preferred in those environments.
We already do this using the "browser" field so the "browser" condition
applies here too.
I don't think it's necessary, but I also specified "worker" explicitly
since this is for Service Workers and those are often targeted with
Web Pack's "webworker" target, which is also what Cloudflare currently
recommends.
I also added "deno" but deno is a bit special because this only works if
you run with the node compatibility since otherwise you have to specify
absolute URLs for the imports.
* RawEventEmitter: new event perf profiling mechanism outside of Pressability to capture all touch events, and other event types
* sync
* concise notation
* Move event telemetry event emitter call from Plugin to ReactFabricEventEmitter, to reduce reliance on the plugin system and move the emit call further into the core
* Backout changes to ReactNativeEventPluginOrder
* Properly flow typing event emitter, and emit event to two channels: named and catchall
* fix typing for event name string
* fix typing for event name string
* fix flow
* Add more comments about how the event telemetry system works
* Add more comments about how the event telemetry system works
* rename to RawEventTelemetryEventEmitterOffByDefault
* yarn prettier-all
* rename event
* comments
* improve flow types
* renamed file
* [RFC] Add onHydrationError option to hydrateRoot
This is not the final API but I'm pushing it for discussion purposes.
When an error is thrown during hydration, we fallback to client
rendering, without triggering an error boundary. This is good because,
in many cases, the UI will recover and the user won't even notice that
something has gone wrong behind the scenes.
However, we shouldn't recover from these errors silently, because the
underlying cause might be pretty serious. Server-client mismatches are
not supposed to happen, even if UI doesn't break from the users
perspective. Ignoring them could lead to worse problems later. De-opting
from server to client rendering could also be a significant performance
regression, depending on the scope of the UI it affects.
So we need a way to log when hydration errors occur.
This adds a new option for `hydrateRoot` called `onHydrationError`. It's
symmetrical to the server renderer's `onError` option, and serves the
same purpose.
When no option is provided, the default behavior is to schedule a
browser task and rethrow the error. This will trigger the normal browser
behavior for errors, including dispatching an error event. If the app
already has error monitoring, this likely will just work as expected
without additional configuration.
However, we can also expose additional metadata about these errors, like
which Suspense boundaries were affected by the de-opt to client
rendering. (I have not exposed any metadata in this commit; API needs
more design work.)
There are other situations besides hydration where we recover from an
error without surfacing it to the user, or notifying an error boundary.
For example, if an error occurs during a concurrent render, it could be
due to a data race, so we try again synchronously in case that fixes it.
We should probably expose a way to log these types of errors, too. (Also
not implemented in this commit.)
* Log all recoverable errors
This expands the scope of onHydrationError to include all errors that
are not surfaced to the UI (an error boundary). In addition to errors
that occur during hydration, this also includes errors that recoverable
by de-opting to synchronous rendering. Typically (or really, by
definition) these errors are the result of a concurrent data race;
blocking the main thread fixes them by prevents subsequent races.
The logic for de-opting to synchronous rendering already existed. The
only thing that has changed is that we now log the errors instead of
silently proceeding.
The logging API has been renamed from onHydrationError
to onRecoverableError.
* Don't log recoverable errors until commit phase
If the render is interrupted and restarts, we don't want to log the
errors multiple times.
This change only affects errors that are recovered by de-opting to
synchronous rendering; we'll have to do something else for errors
during hydration, since they use a different recovery path.
* Only log hydration error if client render succeeds
Similar to previous step.
When an error occurs during hydration, we only want to log it if falling
back to client rendering _succeeds_. If client rendering fails,
the error will get reported to the nearest error boundary, so there's
no need for a duplicate log.
To implement this, I added a list of errors to the hydration context.
If the Suspense boundary successfully completes, they are added to
the main recoverable errors queue (the one I added in the
previous step.)
* Log error with queueMicrotask instead of Scheduler
If onRecoverableError is not provided, we default to rethrowing the
error in a separate task. Originally, I scheduled the task with
idle priority, but @sebmarkbage made the good point that if there are
multiple errors logs, we want to preserve the original order. So I've
switched it to a microtask. The priority can be lowered in userspace
by scheduling an additional task inside onRecoverableError.
* Only use host config method for default behavior
Redefines the contract of the host config's logRecoverableError method
to be a default implementation for onRecoverableError if a user-provided
one is not provided when the root is created.
* Log with reportError instead of rethrowing
In modern browsers, reportError will dispatch an error event, emulating
an uncaught JavaScript error. We can do this instead of rethrowing
recoverable errors in a microtask, which is nice because it avoids any
subtle ordering issues.
In older browsers and test environments, we'll fall back
to console.error.
* Naming nits
queueRecoverableHydrationErrors -> upgradeHydrationErrorsToRecoverable
This deletes some internal behavior that was only used by
useOpaqueIdentifier, as an implementation detail: if an update is
scheduled during the render phase, and something threw an error, we
would try rendering again, either until there were no more errors or
until there were no more render phase updates. This was not a publicly
defined behavior — regular render phase updates are accompanied by
a warning.
Because useOpaqueIdentifier has been replaced by useId, and does not
rely on this implementation detail, we can delete this code.
Refactor DevTools to record Timeline data (in memory) while profiling. Updated the Profiler UI to import/export Timeline data along with legacy profiler data.
Relates to issue #22529
* add failing test for renderToPipeableStream
* Fix context providers in SSR when handling multiple requests. Closes#23089
* Add sibling regression test
Co-authored-by: zhuyi01 <zhuyi01@ke.com>
Co-authored-by: Dan Abramov <dan.abramov@me.com>
Previously we crawled all subtrees, even not-yet-mounted ones, to initialize context values. This was not only unecessary, but it also caused an error to be thrown. This commit adds a test and fixes that behavior.
There was a bug that occurred when a destroy effect is called that causes an update. The update would be added to the updaters list even though the fiber that was calling the destroy effect was unmounted and no longer exists. This PR:
* Adds a patch to Devtools to filter out all in the update list that aren't in the fiberToIDMap (which contains all fibers currently on screen)
Numbers in JavaScript can have precision issues due to how they are encoded. This shows up in snapshot tests sometimes with values like 0.0009999999999999992, which makes the tests hard to read and visually diff.
This PR adds a new snapshot serializers which clamps numbers at 3 decimal points (e.g. the above number 0.0009999999999999992 is serialized as 0.001). This new serializer does not impact non-numeric values, integers, and special numbers like NaN and Infinity.
This gives DevTools a way to detect whether the current React renderer supports Timeline profiling. (Version alone isn't enough to detect this, neither is general profiling support– since these two are controlled by different feature flags.)
* Bypass react event system for custom elements
* Going to try fixing react event system instead
* finally got it to call onChange, but perhaps too many times
* update test
* Removed ReactDOMComponent changes, now works but still doubles for bubbles
* Maybe i should only support bubbling events
* removed some old stuff
* cleaned up changeeventplugin stuff
* prettier, lint
* removed changeeventplugin stuff
* remove unneeded gate for onInput test
* Go back to using ChangeEventPlugin
* Add input+change test
* lint
* Move logic to shouldUseChangeEvent
* use memoizedProps instead of pendingProps
* Run form control behavior before custom element behavior
* add bubbling test
* forgot to append container to body
* add child event target test
* expand <input is=...> test expectations
* Make tests more realistic
* Add extra test
* Add missing gating
* Actually fix gating
Co-authored-by: Dan Abramov <dan.abramov@me.com>
* Failing test for Context.Consumer in suspended Suspense
See issue #19701.
* Fix context propagation for offscreen trees
* Address nits
* Specify propagation root for Suspense too
* Pass correct propagation root
* Harden test coverage
This test will fail if we remove propagation, or if we propagate with a root node like fiber.return or fiber.return.return. The additional DEV-only error helps detect a different kind of mistake, like if the thing being passed hasn't actually been encountered on the way up. However, we still leave the actual production loop to check against null so that there is no way we loop forever if the propagation root is wrong.
* Remove superfluous warning
Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
Until now, DEV and PROFILING builds of React recorded Timeline profiling data using the User Timing API. This commit changes things so that React records this data by calling methods on the DevTools hook. (For now, DevTools still records that data using the User Timing API, to match previous behavior.)
This commit is large but most of it is just moving things around:
* New methods have been added to the DevTools hook (in "backend/profilingHooks") for recording the Timeline performance events.
* Reconciler's "ReactFiberDevToolsHook" has been updated to call these new methods (when they're present).
* User Timing method calls in "SchedulingProfiler" have been moved to DevTools "backend/profilingHooks" (to match previous behavior, for now).
* The old reconciler tests, "SchedulingProfiler-test" and "SchedulingProfilerLabels-test", have been moved into DevTools "TimelineProfiler-test" to ensure behavior didn't change unexpectedly.
* Two new methods have been added to the injected renderer interface: injectProfilingHooks() and getLaneLabelMap().
Relates to #22529.
This is part of the new custom element features that were implemented
here:
https://github.com/facebook/react/commit/24dd07bd269590ee5024b7f0f1906887d256ea86
When a custom element has a setter for a property and passes the `in`
heuristic, the value passed to the react property should be assigned
directly to the custom element's property, regardless of the type of the
value. However, it was discovered that this isn't working with
functions. This patch makes it work with functions.
Fixes https://github.com/facebook/react/issues/23041
* Add --no-show-signature to "git show" commands.
This fixes errors if the user has configured the following in their ~/.gitconfig:
[log]
showSignature = true
* yarn prettier-all
* DevTools: Only show StrictMode badge on root elements
Showing an inline non-compliance badge for every element in the tree is noisy. This commit changes it so that we only show inline icons for root elements (although we continue to show an icon for inspected elements regardless).