Commit Graph

1374 Commits

Author SHA1 Message Date
Dan Abramov
842ee367e6 [Flight] Rename the shared entry point (#20420)
* [Flight] Rename the shared entry point

* Shared
2020-12-10 02:14:50 +00:00
Dan Abramov
dbf40ef759 Put .server.js at the end of bundle filenames (#20419)
* Put .server.js at the end of bundle filenames

* Client too
2020-12-09 22:47:17 +00:00
Dan Abramov
03126dd087 [Flight] Add read-only fs methods (#20412)
* Don't allocate the inner cache unnecessarily

We only need it when we're asking for text. I anticipate I'll want to avoid allocating it in other methods too when it's not strictly necessary.

* Add fs.access

* Add fs.lstat

* Add fs.stat

* Add fs.readdir

* Add fs.readlink

* Add fs.realpath

* Rename functions to disambiguate two caches
2020-12-09 21:46:50 +00:00
Dan Abramov
6a4b12b81c [Flight] Add rudimentary FS binding (#20409)
* [Flight] Add rudimentary FS binding

* Throw for unsupported

* Don't mess with hidden class

* Use absolute path as the key

* Warn on relative and non-normalized paths
2020-12-09 02:37:29 +00:00
Sebastian Markbåge
5fd9db732d [Flight] Rename react-transport-... packages to react-server-... (#20403)
* Move files

* Update paths

* Rename import variables

* Rename /server to /writer

This is mainly because "React Server Server" is weird so we need another
dimension.

* Use "react-server" convention to enforce that writer is only loaded in a server
2020-12-08 08:08:57 -05:00
Sebastian Markbåge
30dfb86025 [Flight] Basic scan of the file system to find Client modules (#20383)
* Basic scan of the file system to find Client modules

This does a rudimentary merge of the plugins. It still uses the global
scan and writes to file system.

Now the plugin accepts a search path or a list of referenced client files.
In prod, the best practice is to provide a list of files that are actually
referenced rather than including everything possibly reachable. Probably
in dev too since it's faster.

This is using the same convention as the upstream ContextModule - which
powers the require.context helpers.

* Add neo-async to dependencies
2020-12-07 12:10:18 -05:00
Dan Abramov
9b8060041b Error when the number of parameters to a query changes (#20379) 2020-12-04 20:11:00 +00:00
Dan Abramov
60e4a76fa8 [Flight] Add rudimentary PG binding (#20372)
* [Flight] Add rudimentary PG binding

* Use nested Maps for parameters

* Inline and fix Flow
2020-12-04 17:27:33 +00:00
Dan Abramov
41c5d00fc9 [Flight] Minimal webpack plugin (#20228) 2020-12-03 21:21:19 +00:00
Dan Abramov
e23673b511 [Flight] Add getCacheForType() to the dispatcher (#20315)
* Remove react/unstable_cache

We're probably going to make it available via the dispatcher. Let's remove this for now.

* Add readContext() to the dispatcher

On the server, it will be per-request.

On the client, there will be some way to shadow it.

For now, I provide it on the server, and throw on the client.

* Use readContext() from react-fetch

This makes it work on the server (but not on the client until we implement it there.)

Updated the test to use Server Components. Now it passes.

* Fixture: Add fetch from a Server Component

* readCache -> getCacheForType<T>

* Add React.unstable_getCacheForType

* Add a feature flag

* Fix Flow

* Add react-suspense-test-utils and port tests

* Remove extra Map lookup

* Unroll async/await because build system

* Add some error coverage and retry

* Add unstable_getCacheForType to Flight entry
2020-12-03 03:44:56 +00:00
Sebastian Markbåge
ad6f3d5c55 Ignore node_modules when printing warnings (#20363)
This now finds acorn and fails to extract warnings from it. But also, this
seems slow.
2020-12-01 08:01:16 -08:00
Sebastian Markbåge
3f73dcee37 Support named exports from client references (#20312)
* Rename "name"->"filepath" field on Webpack module references

This field name will get confused with the imported name or the module id.

* Switch back to transformSource instead of getSource

getSource would be more efficient in the cases where we don't need to read
the original file but we'll need to most of the time.

Even then, we can't return a JS file if we're trying to support non-JS
loader because it'll end up being transformed.

Similarly, we'll need to parse the file and we can't parse it before it's
transformed. So we need to chain with other loaders that know how.

* Add acorn dependency

This should be the version used by Webpack since we have a dependency on
Webpack anyway.

* Parse exported names of ESM modules

We need to statically resolve the names that a client component will
export so that we can export a module reference for each of the names.

For export * from, this gets tricky because we need to also load the
source of the next file to parse that. We don't know exactly how the
client is built so we guess it's somewhat default.

* Handle imported names one level deep in CommonJS using a Proxy

We use a proxy to see what property the server access and that will tell
us which property we'll want to import on the client.

* Add export name to module reference and Webpack map

To support named exports each name needs to be encoded as a separate
reference. It's possible with module splitting that different exports end
up in different chunks.

It's also possible that the export is renamed as part of minification.
So the map also includes a map from the original to the bundled name.

* Special case plain CJS requires and conditional imports using __esModule

This models if the server tries to import .default or a plain require.
We should replicate the same thing on the client when we load that
module reference.

* Dedupe acorn-related deps

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
2020-11-30 14:37:27 -08:00
Sebastian Markbåge
565148d751 Disallow *.server.js imports from any other files (#20309)
This convention ensures that you can declare that you intend for a file
to only be used on the server (even if it technically might resolve
on the client).
2020-11-30 14:25:56 -08:00
Sebastian Markbåge
d93b58a5e3 Add flight specific entry point for react package (#20304)
This configures the Flight fixture to use the "react-server" environment.

This allows the package.json exports field to specify a different resolution
in this environment.

I use this in the "react" package to resolve to a new bundle that excludes
the Hooks that aren't relevant in this environment like useState and useEffect.

This allows us to error early if these names are imported. If we actually
published ESM, it would we a static error. Now it's a runtime error.

You can test this by importing useState in Container.js which is used
by the client and server.
2020-11-20 08:47:13 -08:00
Dan Abramov
89d4fe141a Exclude fixtures from Flow config (#20302) 2020-11-20 02:45:03 +00:00
Sebastian Markbåge
82e99e1b02 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 Clark
765e89b908 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
Andrew Clark
bd8bc5afce 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 Clark
453df3ff72 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 Clark
73bf2d68ef 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
Sebastian Markbåge
504222dcd2 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
Sebastian Markbåge
163199d8cc Dedupe module id generation (#20172) 2020-11-10 19:58:58 -08:00
Sebastian Markbåge
76a6dbcb9a [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åge
35e53b4653 [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
Ricky
0898660154 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
Sebastian Markbåge
c3e20f18fe 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
Ricky
454c2211c0 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åge
56e9feead0 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åge
ffd8423356 [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
Dan Abramov
6d50a9d090 Fixture: Legacy JSX Runtimes (#20012)
* Fixture: Legacy JSX Runtimes

* Add more comments
2020-10-14 18:28:03 +01:00
Ricky
880587366d Deprecate old test script commands (#19893)
* Deprecate old test script commands

* Update PR template test script

* Add test-stable and test-www-classic

* Update circle test names

* Rename test-www-classic to test-classic

* Missed some job renames

* Missed some more job renames
2020-10-14 08:54:34 -04:00
Nick Reiley
7e405d458d [DevTools] Add DevTools forked Feature flags (#18994)
Also resolve an uncaught error in extension build (#18843).

Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-10-12 13:07:10 -04:00
Sebastian Markbåge
0a4c7c5651 [Flight] Don't warn for key, but error for ref (#19986)
* Improve error message by expanding the object in question

* Don't warn for key/ref getters

* Error if refs are passed in server components or to client components
2020-10-08 17:02:23 -07:00
Sebastian Markbåge
40c52de960 [Flight] Add Runtime Errors for Non-serializable Values (#19980)
* Error on encoding non-serializable props

* Add DEV time warnings to enforce that values are plain objects
2020-10-08 11:11:15 -07:00
Dan Abramov
c91c1c4ebe Release script: allow preparing RC from npm 2020-09-22 14:27:50 +01:00
Andrew Clark
e7b255341b Internal act: Flush timers at end of scope (#19788)
If there are any suspended fallbacks at the end of the `act` scope,
force them to display by running the pending timers (i.e. `setTimeout`).

The public implementation of `act` achieves the same behavior with an
extra check in the work loop (`shouldForceFlushFallbacks`). Since our
internal `act` needs to work in both development and production, without
additional runtime checks, we instead rely on Jest's mock timers.

This doesn't not affect refresh transitions, which are meant to delay
indefinitely, because in that case we exit the work loop without
posting a timer.
2020-09-08 21:55:23 -07:00
Andrew Clark
1665443603 Rename effect fields (#19755)
- `effectTag` -> `flags`
- `subtreeTag` -> `subtreeFlags`
2020-09-04 14:34:07 -07:00
Pascal Fong Kye
1396e4a8f5 Fixes eslint warning when node type is ChainExpression (#19680)
* Add babel parser which supports ChainExpression

* Add and fix tests for new babel eslint parser

* extract function to mark node

* refactor for compatibility with eslint v7.7.0+

* Update eslint to v7.7.0
Update hook test since eslint now supports nullish coalescing
2020-08-29 21:03:23 +01:00
Dan Abramov
c1ac052158 [Flight] Support more element types and Hooks for Server and Hybrid Components (#19711)
* Shim support for more element types

* Shim commonly used Hooks that are safe

* Flow

* Oopsie
2020-08-27 20:19:13 +01:00
Andrew Clark
8da0da0937 Disable timeoutMs argument (#19703)
* Remove distinction between long, short transitions

We're removing the `timeoutMs` option, so there's no longer any
distinction between "short" and "long" transitions. They're all treated
the same.

This commit doesn't remove `timeoutMs` yet, only combines the internal
priority levels.

* Disable `timeoutMs` argument

tl;dr
-----

- We're removing the `timeoutMs` argument from `useTransition`.
- Transitions will either immediately switch to a skeleton/placeholder
  view (when loading new content) or wait indefinitely until the data
  resolves (when refreshing stale content).
- This commit disables the `timeoutMS` so that the API has the desired
  semantics. It doesn't yet update the types or migrate all the test
  callers. I'll do those steps in follow-up PRs.

Motivation
----------

Currently, transitions initiated by `startTransition` / `useTransition`
accept a `timeoutMs` option. You can use this to control the maximum
amount of time that a transition is allowed to delay before we give up
and show a placeholder.

What we've discovered is that, in practice, every transition falls into
one of two categories: a **load** or a **refresh**:

- **Loading a new screen**: show the next screen as soon as possible,
  even if the data hasn't finished loading. Use a skeleton/placeholder
  UI to show progress.
- **Refreshing a screen that's already visible**: keep showing the
  current screen indefinitely, for as long as it takes to load the fresh
  data, even if the current data is stale. Use a pending state (and
  maybe a busy indicator) to show progress.

In other words, transitions should either *delay indefinitely* (for a
refresh) or they should show a placeholder *instantly* (for a load).
There's not much use for transitions that are delayed for a
small-but-noticeable amount of time.

So, the plan is to remove the `timeoutMs` option. Instead, we'll assign
an effective timeout of `0` for loads, and `Infinity` for refreshes.

The mechanism for distinguishing a load from a refresh already exists in
the current model. If a component suspends, and the nearest Suspense
boundary hasn't already mounted, we treat that as a load, because
there's nothing on the screen. However, if the nearest boundary is
mounted, we treat that as a refresh, since it's already showing content.

If you need to fix a transition to be treated as a load instead of a
refresh, or vice versa, the solution will involve rearranging the
location of your Suspense boundaries. It may also involve adding a key.

We're still working on proper documentation for these patterns. In the
meantime, please reach out to us if you run into problems that you're
unsure how to fix.

We will remove `timeoutMs` from `useDeferredValue`, too, and apply the
same load versus refresh semantics to the update that spawns the
deferred value.

Note that there are other types of delays that are not related to
transitions; for example, we will still throttle the appearance of
nested placeholders (we refer to this as the placeholder "train model"),
and we may still apply a Just Noticeable Difference heuristic (JND) in
some cases. These aren't going anywhere. (Well, the JND heuristic might
but for different reasons than those discussed above.)
2020-08-26 14:35:13 -07:00
Andrew Clark
af219cc6e6 Lint rule to forbid access of cross-fork fields (#19679)
* Lint rule to forbid access of cross-fork fields

We use a shared Fiber type for both reconciler forks (old and new). It
is a superset of all the fields used by both forks. However, there are
some fields that should only be used in the new fork, and others that
should only be used in the old fork.

Ideally we would enforce this with separate Flow types for each fork.
The problem is that the Fiber type is accessed by some packages outside
the reconciler (like React DOM), and get passed into the reconciler as
arguments. So there's no way to fork the Fiber type without also forking
the packages where they are used. FiberRoot has the same issue.

Instead, I've added a lint rule that forbids cross-fork access of
fork-specific fields. Fields that end in `_old` or `_new` are forbidden
from being used inside the new or old fork respectively. Or you can
specific custom fields using the ESLint plugin options.

I used this plugin to find and remove references to the effect list
in d2e914a.

* Mark effect list fields as old

And `subtreeTag` as new.

I didn't mark `lastEffect` because that name is also used by the
Hook type. Not super important; could rename to `lastEffect_old` but
idk if it's worth the effort.
2020-08-24 10:07:11 -07:00
Dan Abramov
848bb2426e Attach Listeners Eagerly to Roots and Portal Containers (#19659)
* Failing test for #19608

* Attach Listeners Eagerly to Roots and Portal Containers

* Forbid createEventHandle with custom events

We can't support this without adding more complexity. It's not clear that this is even desirable, as none of our existing use cases need custom events. This API primarily exists as a deprecation strategy for Flare, so I don't think it is important to expand its support beyond what Flare replacement code currently needs. We can later revisit it with a better understanding of the eager/lazy tradeoff but for now let's remove the inconsistency.

* Reduce risk by changing condition only under the flag

Co-authored-by: koba04 <koba0004@gmail.com>
2020-08-24 16:50:20 +01:00
Julien Gilli
b8fa09e9e2 provide profiling bundle for react-reconciler (#19559) 2020-08-19 14:11:27 +01:00
Timothy Yung
1a41a196bc Append text string to <Text> error message (#19581)
* Append text string to <Text> error message

* Truncate text in <Text> error message

* Regenerate `codes.json`
2020-08-17 10:47:49 -07:00
CY Lim
702fad4b1b refactor fb.me redirect link to reactjs.org/link (#19598)
* refactor fb.me url to reactjs.org/link

* Update ESLintRuleExhaustiveDeps-test.js

* Update ReactDOMServerIntegrationUntrustedURL-test.internal.js

* Update createReactClassIntegration-test.js

* Update ReactDOMServerIntegrationUntrustedURL-test.internal.js

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
2020-08-17 13:25:50 +01:00
Toru Kobayashi
49cd77d24a fix: leak strict mode with UMD builds (#19614) 2020-08-15 14:42:49 +01:00
Andrew Clark
b8ed6a1aa5 [Scheduler] Call postTask directly (#19551)
This updates the experimental Scheduler postTask build to call postTask
directly, instead of managing our own custom queue and work loop.

We still use a deadline 5ms mechanism to implement `shouldYield`.

The main thing that postTask is currently missing is the continuation
feature — when yielding to the main thread, the yielding task is sent
to the back of the queue, instead of maintaining its position.

While this would be nice to have, even without it, postTask may be good
enough to replace our userspace implementation.

We'll run some tests to see.
2020-08-12 08:39:47 -05:00
Andrew Clark
0cd9a6de55 Parallelize Jest in CI (#19552)
Uses CircleCI's `parallelism` key to split our test jobs across multiple
processes, like we do for the build job.
2020-08-07 16:32:59 -04:00
Dan Abramov
2d9ec9199c Indent a command 2020-08-07 19:24:49 +01:00
Dan Abramov
db2f229110 Fix command 2020-08-07 19:23:43 +01:00