Commit Graph

256 Commits

Author SHA1 Message Date
Josh Story
e7fc04b297 [react-dom] Reorganize react-dom internals to match react (#25277)
* reorganize react-dom internals to match react

* refactor and make forks work for flow and internal imports

* flew too close to the sun

* typo
2022-09-15 15:31:31 -07:00
Ricky
0de3ddf56e Remove Symbol Polyfill (again) (#25144) 2022-08-25 17:01:30 -04:00
Andrew Clark
a7b192e0f1 Add test gate alias for Offscreen (#24749)
Offscreen is only enabled in the www and experimental channels. Instead
of listing these on every Offscreen test, I added a test gate alias
called `enableOffscreen`. Makes it easier to grep for these, and edit or
remove the channels later.
2022-06-30 09:44:54 -04:00
Alexandru Tasica
2c68776abe fix scripts folder text (#24609) 2022-05-25 09:56:35 -04:00
Luna Ruan
1e98682dd3 [DevTools] Fix moduleNameMapper Order in DevTools Config #24602)
We need the regression config moduleNameMapper to come before the current moduleNameMapper so when it tries to map "/^react-dom\/([^/]+)$/ it doesn't get confused. The reason is because order in which the mappings are defined matters. Patterns are checked one by one until one fits, and the most specific rule should be listed first.
2022-05-23 14:18:17 -07:00
Luna Ruan
5a1e558df2 [DevTools] Regression Test Jest Config (#24598)
Some older React versions have different module import names and are missing certain features. This PR mocks modules that don't exist and maps modules in older versions to the ones that are required in tests. Specifically:

* In React v16.5, scheduler is named schedule
* In pre concurrent React, there is no act
* Prior to React v18.0, react-dom/client doesn't exist
* In DevTools, we expect to use scheduler/tracing-profiling instead of scheduler/tracing
2022-05-23 13:50:53 -04:00
Luna Ruan
6e2f38f3a4 [DevTools] Remove string.replaceAll Call in @reactVersion Pragma Functions (#24584)
`string.replaceAll` doesn't exist in our CircleCI Docker environment. We also don't need it in this case because `semver.satisfies` allows for whitespace when specifying a range. This PR removes the unnecessary call.
2022-05-19 09:59:36 -07:00
Andrew Clark
769875806c Add option for source maps when running tests (#24577)
I added a `--sourceMaps` option to our test command that enables inline
source maps. I've kept it disabled by default, since it makes the tests
run slower. But it's super useful when attaching to a debugger.
2022-05-18 13:48:21 -04:00
Luna Ruan
c5e039d9b0 [DevTools] Add jest-cli --reactVersion argument (#24556)
Add `--reactVersion` argument. This argument is only used in DevTools. When this is specified, run only the tests that have the `// @reactVersion` pragma that satisfies the semver version range. Otherwise, run tests as normal
2022-05-16 08:30:43 -07:00
Luna Ruan
4c03bb6ed0 [DevTools] ignore tests without reactVersion pragma if REACT_VERSION specified (#24555)
In DevTools tests, if the REACT_VERSION specified, we know this is a regression test (testing older React Versions). Because a lot of tests test the DevTools front end and we don't want to run them in the regression test scenario, we decided to only run tests that have the // @reactVersion pragma defined.

Because if there are no tests specified, jest will fail, we also opt to use jest.skip to skip all the tests that we don't want to run for a specific React version istead.

This PR makes this change.
2022-05-14 00:54:50 -04:00
Luna Ruan
7d9e17a982 [DevTools] Add Pragma to Only Run Tests if Version Requirement Satisfied (#24533)
This PR:

Adds a transform-react-version-pragma that transforms // @reactVersion SEMVER_VERSION into _test_react_version(...) and _test_react_version_focus(...) that lets us only run a test if it satisfies the right react version.
Adds _test_react_version and _test_react_version_focus to the devtools setupEnv file
Add a devtools preprocessor file for devtools specific plugins
2022-05-11 12:01:05 -04:00
Ricky
6cbf0f7fac Fork ReactSymbols (#24484)
* Fork ReactSymbols

* Fix tests

* Update jest config
2022-05-03 17:12:23 -04:00
Ricky
8dcedba15a Add fallback shim for AbortController (#24285)
* Add fallback shim for AbortController

* Replace shim with a minimal stub

* replace-fork

* Better minification

* Fix flow

* Even smaller

* replace-fork

* Revert back to object constructor

* replace-fork
2022-04-08 15:53:40 -04:00
Sebastian Markbåge
17806594cc Move createRoot/hydrateRoot to react-dom/client (#23385)
* Move createRoot/hydrateRoot to /client

We want these APIs ideally to be imported separately from things you
might use in arbitrary components (like flushSync). Those other methods
are "isomorphic" to how the ReactDOM tree is rendered. Similar to hooks.

E.g. importing flushSync into a component that only uses it on the client
should ideally not also pull in the entry client implementation on the
server.

This also creates a nicer parity with /server where the roots are in a
separate entry point.

Unfortunately, I can't quite do this yet because we have some legacy APIs
that we plan on removing (like findDOMNode) and we also haven't implemented
flushSync using a flag like startTransition does yet.

Another problem is that we currently encourage these APIs to be aliased by
/profiling (or unstable_testing). In the future you don't have to alias
them because you can just change your roots to just import those APIs and
they'll still work with the isomorphic forms. Although we might also just
use export conditions for them.

For that all to work, I went with a different strategy for now where the
real API is in / but it comes with a warning if you use it. If you instead
import /client it disables the warning in a wrapper. That means that if you
alias / then import /client that will inturn import the alias and it'll
just work.

In a future breaking changes (likely when we switch to ESM) we can just
remove createRoot/hydrateRoot from / and move away from the aliasing
strategy.

* Update tests to import from react-dom/client

* Fix fixtures

* Update warnings

* Add test for the warning

* Update devtools

* Change order of react-dom, react-dom/client alias

I think the order matters here. The first one takes precedence.

* Require react-dom through client so it can be aliased

Co-authored-by: Andrew Clark <git@andrewclark.io>
2022-03-01 00:13:28 -05:00
Brian Vaughn
fa816be7f0 DevTools: Timeline profiler refactor
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
2022-01-28 13:09:28 -05:00
Brian Vaughn
a637084320 DevTools: Add Jest snapshot serializer for number formatting (#23139)
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.
2022-01-20 15:52:17 -05:00
Brian Vaughn
51947a14bb Refactored how React/DevTools log Timeline performance data (#23102)
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.
2022-01-13 14:55:54 -05:00
Andrew Covenant
fe419346da Console message fixed for devtools (#23067) 2022-01-05 11:45:45 -05:00
Andrew Clark
83564712b6 Move SuspenseList to experimental channel (#22765)
There's more work to be done to implement this correctly on the server,
so we're going to wait to release it until an 18.x minor.
2021-11-15 10:12:56 -08:00
MalikIdreesHasanKhan
489b4bdcca Fixed typos (#22763)
* Fixed typos

* Update ReactFiberWorkLoop.new.js

* Update ReactFiberWorkLoop.old.js
2021-11-15 12:31:35 -05:00
Andrew Clark
6bce0355c3 Upgrade useSyncExternalStore to alpha channel (#22662)
* Move useSyncExternalStore shim to a nested entrypoint

Also renames `useSyncExternalStoreExtra` to
`useSyncExternalStoreWithSelector`.

- 'use-sync-external-store/shim' -> A shim for `useSyncExternalStore`
  that works in React 16 and 17 (any release that supports hooks). The
  module will first check if the built-in React API exists, before
  falling back to the shim.
- 'use-sync-external-store/with-selector' -> An extended version of
  `useSyncExternalStore` that also supports `selector` and `isEqual`
  options. It does _not_ shim `use-sync-external-store`; it composes the
  built-in React API. **Use this if you only support 18+.**
- 'use-sync-external-store/shim/with-selector' -> Same API, but it
  composes `use-sync-external-store/shim` instead. **Use this for
  compatibility with 16 and 17.**
- 'use-sync-external-store' -> Re-exports React's built-in API. Not
  meant to be used. It will warn and direct users to either the shim or
  the built-in API.

* Upgrade useSyncExternalStore to alpha channel
2021-10-31 15:38:03 -07:00
Andrew Clark
7034408ff7 Follow-up improvements to error code extraction infra (#22516)
* Output FIXME during build for unminified errors

The invariant Babel transform used to output a FIXME comment if it
could not find a matching error code. This could happen if there were
a configuration mistake that caused an unminified message to
slip through.

Linting the compiled bundles is the most reliable way to do it because
there's not a one-to-one mapping between source modules and bundles. For
example, the same source module may appear in multiple bundles, some
which are minified and others which aren't.

This updates the transform to output the same messages for Error calls.

The source lint rule is still useful for catching mistakes during
development, to prompt you to update the error codes map before pushing
the PR to CI.

* Don't run error transform in development

We used to run the error transform in both production and development,
because in development it was used to convert `invariant` calls into
throw statements.

Now that don't use `invariant` anymore, we only have to run the
transform for production builds.

* Add ! to FIXME comment so Closure doesn't strip it

Don't love this solution because Closure could change this heuristic,
or we could switch to a differnt compiler that doesn't support it. But
it works.

Could add a bundle that contains an unminified error solely for the
purpose of testing it, but that seems like overkill.

* Alternate extract-errors that scrapes artifacts

The build script outputs a special FIXME comment when it fails to minify
an error message. CI will detect these comments and fail the workflow.

The comments also include the expected error message. So I added an
alternate extract-errors that scrapes unminified messages from the
build artifacts and updates `codes.json`.

This is nice because it works on partial builds. And you can also run it
after the fact, instead of needing build all over again.

* Disable error minification in more bundles

Not worth it because the number of errors does not outweight the size
of the formatProdErrorMessage runtime.

* Run extract-errors script in CI

The lint_build job already checks for unminified errors, but the output
isn't super helpful.

Instead I've added a new job that runs the extract-errors script and
fails the build if `codes.json` changes. It also outputs the expected
diff so you can easily see which messages were missing from the map.

* Replace old extract-errors script with new one

Deletes the old extract-errors in favor of extract-errors2
2021-10-31 15:37:32 -07:00
Joseph Savona
fa9bea0c41 Initial implementation of cache cleanup (#22510)
This is an initial, partial implementation of a cleanup mechanism for the experimental Cache API. The idea is that consumers of the Cache API can register to be informed when a given Cache instance is no longer needed so that they can perform associated cleanup tasks to free resources stored in the cache. A canonical example would be cancelling pending network requests.

An overview of the high-level changes:

* Changes the `Cache` type from a Map of cache instances to be an object with the original Map of instances, a reference count (to count roughly "active references" to the cache instances - more below), and an AbortController.
* Adds a new public API, `unstable_getCacheSignal(): AbortSignal`, which is callable during render. It returns an AbortSignal tied to the lifetime of the cache - developers can listen for the 'abort' event on the signal, which React now triggers when a given cache instance is no longer referenced. 
  * Note that `AbortSignal` is a web standard that is supported by other platform APIs; for example a signal can be passed to `fetch()` to trigger cancellation of an HTTP request.
* Implements the above - triggering the 'abort' event - by handling passive mount/unmount for HostRoot and CacheComponent fiber nodes.

Cases handled:
* Aborted transitions: we clean up a new cache created for an aborted transition
* Suspense: we retain a fresh cache instance until a suspended tree resolves

For follow-ups:
* When a subsequent cache refresh is issued before a previous refresh completes, the refreshes are queued. Fresh cache instances for previous refreshes in the queue should be cleared, retaining only the most recent cache. I plan to address this in a follow-up PR.
* If a refresh is cancelled, the fresh cache should be cleaned up.
2021-10-21 14:11:42 -07:00
Brian Vaughn
c16b005f2d Update test and stack frame code to support newer V8 stack formats (#22477) 2021-10-11 18:40:42 -04:00
Brian Vaughn
cadf94df1f Add new Jest --compact-console flag for DevTools tests (#22495) 2021-10-05 11:58:54 -04:00
Andrew Clark
bb0d069359 [build2 -> build] Local scripts
Update all our local scripts to use `build` instead of `build2`.

There are still downstream scripts that depend on `build2`, though, so
we can't remove it yet.
2021-09-21 15:14:09 -04:00
Andrew Clark
33226fadaa Check for store mutations before commit (#22290)
* [useSyncExternalStore] Remove extra hook object

Because we already track `getSnapshot` and `value` on the store
instance, we don't need to also track them as effect dependencies. And
because the effect doesn't require any clean-up, we don't need to track
a `destroy` function.

So, we don't need to store any additional state for this effect. We can
call `pushEffect` directly, and only during renders where something
has changed.

This saves some memory, but my main motivation is because I plan to use
this same logic to schedule a pre-commit consistency check. (See the
inline comments for more details.)

* Split shouldTimeSlice into two separate functions

Lanes that are blocking (SyncLane, and DefaultLane inside a blocking-
by-default root) are always blocking for a given root. Whereas expired
lanes can expire while the render phase is already in progress.

I want to check if a lane is blocking without checking whether it
expired, so I split `shouldTimeSlice` into two separate functions.

I'll use this in the next step.

* Check for store mutations before commit

When a store is read for the first time, or when `subscribe` or
`getSnapshot` changes, during a concurrent render, we have to check
at the end of the render phase whether the store was mutated by
an concurrent event.

In the userspace shim, we perform this check in a layout effect, and
patch up any inconsistencies by scheduling another render + commit.
However, even though we patch them up in the next render, the parent
layout effects that fire in the original render will still observe an
inconsistent tree.

In the native implementation, we can instead check for inconsistencies
right after the root is completed, before entering the commit phase. If
we do detect a mutaiton, we can discard the tree and re-render before
firing any effects. The re-render is synchronous to block further
concurrent mutations (which is also what we do to recover from tearing
bugs that result in an error). After the synchronous re-render, we can
assume the tree the tree is consistent and continue with the normal
algorithm for finishing a completed root (i.e. either suspend
or commit).

The result is that layout effects will always observe a consistent tree.
2021-09-13 08:07:46 -07:00
Ricky
e73911e715 Clean up my "hard to read" code (#22295) 2021-09-11 15:05:54 -04:00
Andrew Clark
77912d9a05 Wire up the native API for useSyncExternalStore (#22237)
Adds useSyncExternalStore to the internal dispatcher, and exports
the native API from the React package without yet implementing it.
2021-09-07 10:20:24 -07:00
Brian Vaughn
e07039bb61 Moved named hooks code (and tests) from react-devtools-extensions to react-devtools-shared (#22260) 2021-09-07 11:44:49 -04:00
Andrew Clark
d54be90be6 Set up test infra for dynamic Scheduler flags (#22139)
I copied the set up we use for React.

In the www-variant test job, the Scheduler `__VARIANT__` flags will be
`true`. When writing a test, we can read the value of the flag with the
`gate` pragma and method.

Note: Since these packages are currently released in lockstep, maybe we
should remove SchedulerFeatureFlags and use ReactFeatureFlags for both.
2021-08-20 06:56:20 -07:00
Andrew Clark
81346764bb Run persistent tests in more configurations in CI (#21880)
I noticed that `enableSuspenseLayoutEffectSemantics` is not fully
implemented in persistent mode. I believe this was an oversight
because we don't have a CI job that runs tests in persistent mode and
with experimental flags enabled.

This adds additional test configurations to the CI job so we don't miss
stuff like this again. It doesn't fix the failing tests — I'll address
that separately.
2021-07-14 08:40:20 -07:00
Brian Vaughn
f52b73f9d0 DevTools: Update named hooks match to use column number also (#21833)
This prevents edge cases where AST nodes are incorrectly matched.
2021-07-08 16:12:22 -04:00
Brian Vaughn
c5cfa71948 DevTools: Show hook names based on variable usage (#21641)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
Co-authored-by: Saphal Patro <saphal1998@gmail.com>
Co-authored-by: VibhorCodecianGupta <vibhordelgupta@gmail.com>
2021-07-01 14:39:18 -04:00
Brian Vaughn
8426bb6956 Pass Jest useStderr flag when debugging (#21741)
This prevents it from buffering adn suppressing all console logs until a test has completed running (When debugging in Chrome).
2021-06-23 16:58:46 -04:00
Andrew Clark
d7dce572c7 Remove internal act builds from public modules (#21721)
* Move internal version of act to shared module

No reason to have three different copies of this anymore.

I've left the the renderer-specific `act` entry points because legacy
mode tests need to also be wrapped in `batchedUpdates`. Next, I'll update
the tests to use `batchedUpdates` manually when needed.

* Migrates tests to use internal module directly

Instead of the `unstable_concurrentAct` exports. Now we can drop those
from the public builds.

I put it in the jest-react package since that's where we put our other
testing utilities (like `toFlushAndYield`). Not so much so it can be
consumed publicly (nobody uses that package except us), but so it works
with our build tests.

* Remove unused internal fields

These were used by the old act implementation. No longer needed.
2021-06-22 14:29:35 -07:00
Andrew Clark
06f7b4f43a act should work without mock Scheduler (#21714)
Currently, in a React 18 root, `act` only works if you mock the
Scheduler package. This was because we didn't want to add additional
checks at runtime.

But now that the `act` testing API is dev-only, we can simplify its
implementation.

Now when an update is wrapped with `act`, React will bypass Scheduler
entirely and push its tasks onto a special internal queue. Then, when
the outermost `act` scope exists, we'll flush that queue.

I also removed the "wrong act" warning, because the plan is to move
`act` to an isomorphic entry point, simlar to `startTransition`. That's
not directly related to this PR, but I didn't want to bother
re-implementing that warning only to immediately remove it.

I'll add the isomorphic API in a follow up.

Note that the internal version of `act` that we use in our own tests
still depends on mocking the Scheduler package, because it needs to work
in production. I'm planning to move that implementation to a shared
(internal) module, too.
2021-06-22 14:25:07 -07:00
Andrew Clark
bd0a963445 Throw when act is used in production (#21686)
Upgrades the deprecation warning to a runtime error.

I did it this way instead of removing the export so the type is the same
in both builds. It will get dead code eliminated regardless.
2021-06-16 16:29:51 -04:00
Andrew Clark
aecb3b6d11 Deprecate ReactDOM.render and ReactDOM.hydrate (#21652)
* Use existing test warning filter for server tests

We have a warning filter for our internal tests to ignore warnings
that are too noisy or that we haven't removed from our test suite yet:
shouldIgnoreConsoleError.

Many of our server rendering tests don't use this filter, though,
because it has its own special of asserting warnings.

So I added the warning filter to the server tests, too.

* Deprecate ReactDOM.render and ReactDOM.hydrate

These are no longer supported in React 18. They are replaced by the
`createRoot` API.

The warning includes a link to documentation of the new API. Currently
it redirects to the corresponding working group post. Here's the PR to
set up the redirect: https://github.com/reactjs/reactjs.org/pull/3730

Many of our tests still use ReactDOM.render. We will need to gradually
migrate them over to createRoot.

In the meantime, I added the warnings to our internal warning filter.
2021-06-09 13:46:55 -07:00
Sebastian Markbåge
86715efa23 Resolve the true entry point during tests (#21505)
* Resolve the entry point for tests the same way builds do

This way the source tests, test the same entry point configuration.

* Gate test selectors on www

These are currently only exposed in www builds

* Gate createEventHandle / useFocus on www

These are enabled in both www variants but not OSS experimental.

* Temporarily disable www-modern entry point

Use the main one that has all the exports until we fix more tests.

* Remove enableCache override that's no longer correct

* Open gates for www

These used to not be covered because they used Cache which wasn't exposed.
2021-06-02 18:03:29 -07:00
Sebastian Markbåge
a8a4742f1c Convert ES6/TypeScript/CoffeeScript Tests to createRoot + act (#21598)
* Convert ES6/TypeScript CoffeeScript Tests to createRoot + act

* Change expectation for WWW+VARIANT because the deferRenderPhaseUpdateToNextBatch flag breaks this behavior
2021-06-02 11:36:59 -07:00
Sebastian Markbåge
efbd69b27e Define global __WWW__ = true flag during www tests (#21504)
* Define global __WWW__ = true flag during www tests

We already do that for __PERSISTENT__.

* Use @gate www in ReactSuspenseCallback

This allows it to not be internal anymore. We test it against the www build.
2021-06-01 10:16:06 -07:00
Sebastian Silbermann
3c2341416a Update jest to v26 (#21574)
* Install jest 26

* jsdom env now uses 16 by default

* require.requireActual -> jest.requireActual

* deduplicate added deps
2021-05-27 16:33:57 +01: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
Brian Vaughn
c3cb2c2b30 Fix DevTools test target (#21267) 2021-04-16 16:19:05 -04:00
Andrew Clark
dd8552ae0d yarn test: Default to bleeding edge configuration (#21238)
My personal workflow is to develop against the www-modern release
channel, with the variant flags enabled, because it encompasses the
largest set of features. Then I rely on CI to run the tests against
all the other configurations.

So in practice, I almost always run

```
yarn test -r=www-modern --variant TEST_FILE
```

instead of

```
yarn test TEST_FILE
```

So, I've updated the `yarn test` command to use those options
by default.
2021-04-12 09:49:26 -07:00
Dan Abramov
d857f9e4d0 Land enableSetImmediate feature flag (#20906) 2021-03-01 18:34:12 +00:00
Dan Abramov
0991647921 Use setImmediate when available over MessageChannel (#20834)
* Move direct port access into a function

* Fork based on presence of setImmediate

* Copy SchedulerDOM-test into another file

* Change the new test to use shimmed setImmediate

* Clarify comment

* Fix test to work with existing feature detection

* Add flags

* Disable OSS flag and skip tests

* Use VARIANT to reenable tests

* lol
2021-02-17 21:00:42 +00:00
Andrew Clark
fb3e158a64 Convert ReactSuspenseWithNoopRenderer tests to use built-in cache (#20601)
* Remove `ms` prop from SuspenseWithNoop tests

Use `resolveText` instead.

* Migrate SuspenseWithNoop tests to built-in cache
2021-01-19 14:38:54 -08:00