* [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
* 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
* 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
* 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
* 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>
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).
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.
* 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.
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.
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.
* 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
* 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
* Reduce code to necessities
* Switch to postTask API
* Add SchedulerPostTask tests
* Updates from review
* Fix typo from review
* Generate build of unstable_post_task
We need this so we can version them separately and use different
feature flags than we use for OSS RN.
I put them in a separate facebook-react-native folder which won't go
into the RN GH repo. I plan on moving the renderers there too but not yet.
I don't think we'll ever use this just because we have such a unique set up
for network delivery so we'll use something custom for this case.
Also, we don't need a profiling build for this since it doesn't have an
entry point.
* Lint bundles using the bundle config instead of scanning for files
This ensures that we look for all the files that we expect to see there.
If something doesn't get built we wouldn't detect it.
However, this doesn't find files that aren't part of our builds such as
indirection files in the root. This will need to change with ESM anyway
since indirection files doesn't work. Everything should be built anyway.
This ensures that we can use the bundles.js config to determine special
cases instead of relying on file system conventions.
* Run lint with flag
* Gate test
* Delete entrypoints without Build Outputs from package.json and build output
If an entry point exists in bundles.js but doesn't have any bundleTypes,
I delete that entry point file from the build directory. I also remove it
from the files field in package.json if it exists.
This allows us to remove bundles from being built in the stable release
channel.
* First pass at scaffolding out the Node implementation of react-data.
While incomplete, this patch contains some changes to the react-data
package in order to start adding support for Node.
The first part of this change accounts for splitting react-data/fetch
into two discrete entries, adding (and defaulting to) the Node
implementation.
The second part is sketching out a rough approximation of `fetch` for
Node. This implementation is not complete by any means, but provides a
starting point.
* Remove NodeFetch module and put it directly into ReactDataFetchNode.
* Replaced react-data with react-fetch.
This patch shuffles around some of the scaffolding that was in
react-data in favor of react-fetch. It also removes the additional
"fetch" package in favor of something flatter.
* Tweak package organization
* Simplify and add a test
Co-authored-by: Dan Abramov <dan.abramov@me.com>
* Rename Flight to Transport
Flight is still the codename for the implementation details (like Fiber).
However, now the public package is react-transport-... which is only
intended to be used directly by integrators.
* Rename names
* Rename ReactCache -> ReactCacheOld
We still use it in some tests so I'm going to leave it for now. I'll start making the new one in parallel in the react package.
* Add react/unstable-cache entry point
* Add react-data entry point
* Initial implementation of cache and data/fetch
* Address review
* Eject CRA from Flight
We need to eject because we're going to add a custom Webpack Plugin.
We can undo this once the plugin has upstreamed into CRA.
* Add Webpack plugin build
I call this entry point "webpack-plugin" instead of "plugin" even though
this is a webpack specific package. That's because there will also be a
Node.js plugin to do the server transform.
* Add Flight Webpack plugin to fixture
* Rm UMD builds
* Transform classes
* Rename webpack-plugin to plugin
This avoids the double webpack name. We're going to reuse this for both
server and client.
This is equivalent to the jsx-runtime in that this is what the compiled
output on the server is supposed to target.
It's really just the same code for all the different Flights, but they
have different types in their arguments so each one gets their own entry
point. We might use this to add runtime warnings per entry point.
Unlike the client-side React.block call this doesn't provide the factory
function that curries the load function. The compiler is expected to wrap
this call in the currying factory.
* Resolve Server-side Blocks instead of Components
React elements should no longer be used to extract arbitrary data but only
for prerendering trees.
Blocks are used to create asynchronous behavior.
* Resolve Blocks in the Client
* Tests
* Bug fix relay JSON traversal
It's supposed to pass the original object and not the new one.
* Lint
* Move Noop Module Test Helpers to top level entry points
This module has shared state. It needs to be external from builds.
This lets us test the built versions of the Noop renderer.
This PR adds the jsx-runtime and jsx-dev-runtime modules for the JSX Babel Plugin. WWW still relies on jsx/jsxs/jsxDEV from the "react" module, so once we refactor the code to point to the runtime modules we will remove jsx/jsxs/jsxDEV from the "react" module.
* ReactFiberReconciler -> ReactFiberReconciler.old
* Set up infra for react-reconciler fork
We're planning to land some significant refactors of the reconciler.
We want to be able to gradually roll out the new implementation side-by-
side with the existing one. So we'll create a short lived fork of the
react-reconciler package. Once the new implementation has stabilized,
we'll delete the old implementation and promote the new one.
This means, for as long as the fork exists, we'll need to maintain two
separate implementations. This sounds painful, but since the forks will
still be largely the same, most changes will not require two separate
implementations. In practice, you'll implement the change in the old
fork and then copy paste it to the new one.
This commit only sets up the build and testing infrastructure. It does
not actually fork any modules. I'll do that in subsequent PRs.
The forked version of the reconciler will be used to build a special
version of React DOM. I've called this build ReactDOMForked. It's only
built for www; there's no open source version.
The new reconciler is disabled by default. It's enabled in the
`yarn test-www-variant` command. The reconciler fork isn't really
related to the "variant" feature of the www builds, but I'm piggy
backing on that concept to avoid having to add yet another
testing dimension.
* Add ReactFlightServerConfig intermediate
This just forwards to the stream version of Flight which is itself forked
between Node and W3C streams.
The dom-relay goes directly to the Relay config though which allows it to
avoid the stream part of Flight.
* Separate streaming protocol into the Stream config
* Split streaming parts into the ReactFlightServerConfigStream
This decouples it so that the Relay implementation doesn't have to encode
the JSON to strings. Instead it can be fed the values as JSON objects and
do its own encoding.
* Split FlightClient into a basic part and a stream part
Same split as the server.
* Expose lower level async hooks to Relay
This requires an external helper file that we'll wire up internally.
* Rename to clarify that it's client-only
* Rename FizzStreamer to FizzServer for consistency
* Rename react-flight to react-client/flight
For consistency with react-server. Currently this just includes flight
but it could be expanded to include the whole reconciler.
* Add Relay Flight Build
* Rename ReactServerHostConfig to ReactServerStreamConfig
This will be the config specifically for streaming purposes.
There will be other configs for other purposes.
* Require deep for reconcilers
* Delete inline* files
* Delete react-reconciler/persistent
This no longer makes any sense because it react-reconciler takes
supportsMutation or supportsPersistence as options. It's no longer based
on feature flags.
* Fix jest mocking
* Fix Flow strategy
We now explicitly list which paths we want to be checked by a renderer.
For every other renderer config we ignore those paths.
Nothing is "any" typed. So if some transitive dependency isn't reachable
it won't be accidentally "any" that leaks.