Commit Graph

30 Commits

Author SHA1 Message Date
Josh Story
cb151849e1
[react-dom] move all client code to react-dom/client (#28271)
This PR reorganizes the `react-dom` entrypoint to only pull in code that
is environment agnostic. Previously if you required anything from this
entrypoint in any environment the entire client reconciler was loaded.
In a prior release we added a server rendering stub which you could
alias in server environments to omit this unecessary code. After landing
this change this entrypoint should not load any environment specific
code.

While a few APIs are truly client (browser) only such as createRoot and
hydrateRoot many of the APIs you import from this package are only
useful in the browser but could concievably be imported in shared code
(components running in Fizz or shared components as part of an RSC app).
To avoid making these require opting into the client bundle we are
keeping them in the `react-dom` entrypoint and changing their
implementation so that in environments where they are not particularly
useful they do something benign and expected.

#### Removed APIs
The following APIs are being removed in the next major. Largely they
have all been deprecated already and are part of legacy rendering modes
where concurrent features of React are not available
* `render`
* `hydrate`
* `findDOMNode`
* `unmountComponentAtNode`
* `unstable_createEventHandle`
* `unstable_renderSubtreeIntoContainer`
* `unstable_runWithPrioirty`

#### moved Client APIs
These APIs were available on both `react-dom` (with a warning) and
`react-dom/client`. After this change they are only available on
`react-dom/client`
* `createRoot`
* `hydrateRoot`

#### retained APIs
These APIs still exist on the `react-dom` entrypoint but have normalized
behavior depending on which renderers are currently in scope
* `flushSync`: will execute the function (if provided) inside the
flushSync implemention of FlightServer, Fizz, and Fiber DOM renderers.
* `unstable_batchedUpdates`: This is a noop in concurrent mode because
it is now the only supported behavior because there is no legacy
rendering mode
* `createPortal`: This just produces an object. It can be called from
anywhere but since you will probably not have a handle on a DOM node to
pass to it it will likely warn in environments other than the browser
* preloading APIS such as `preload`: These methods will execute the
preload across all renderers currently in scope. Since we resolve the
Request object on the server using AsyncLocalStorage or the current
function stack in practice only one renderer should act upon the
preload.

In addition to these changes the server rendering stub now just rexports
everything from `react-dom`. In a future minor we will add a warning
when using the stub and in the next major we will remove the stub
altogether
2024-04-24 08:50:32 -07:00
Andrew Clark
857ee8cdf9
Don't minify symbols in production builds (#28881)
This disables symbol renaming in production builds. The original
variable and function names are preserved. All other forms of
compression applied by Closure (dead code elimination, inlining, etc)
are unchanged — the final program is identical to what we were producing
before, just in a more readable form.

The motivation is to make it easier to debug React issues that only
occur in production — the same reason we decided to start shipping
sourcemaps in #28827 and #28827.

However, because most apps run their own minification step on their npm
dependencies, it's not necessary for us to minify the symbols before
publishing — it'll be handled the app, if desired.

This is the same strategy Meta has used to ship React for years. The
React build itself has unminified symbols, but they get minified as part
of Meta's regular build pipeline.

Even if an app does not minify their npm dependencies, gzip covers most
of the cost of symbol renaming anyway.

This saves us from having to ship sourcemaps, which means even apps that
don't have sourcemaps configured will be able to debug the React build
as easily as they would any other npm dependency.
2024-04-20 11:23:46 -04:00
Josh Story
33a32441e9
Remove renderToStaticNodeStream (#28873)
Stacked on #28872 

renderToStaticNodeStream was not originally deprecated when
renderToNodeStream was deprecated because it did not yet have a clear
analog in the modern streaming implementation for SSR. In React 19 we
have already removed renderToNodeStream. This change removes
renderToStaticNodeStream as well because you can replicate it's
semantics using renderToPipeableStream with onAllReady or
renderToReadableStream with await stream.allready.
2024-04-18 21:06:04 -07:00
Sebastian Markbåge
f613165357
Rename SECRET INTERNALS to __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE (#28789)
Follow up to #28783 and #28786.

Since we've changed the implementations of these we can rename them to
something a bit more descriptive while we're at it, since anyone
depending on them will need to upgrade their code anyway.

"react" with no condition:
`__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
"react" with "react-server" condition:
`__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
"react-dom":
`__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
2024-04-09 12:20:22 -04:00
Josh Story
556a087de3
[DOM] disallow client entrypoints with react-server condition (#28784)
`react-server` precludes loading code that expects to be run in a client
context. This includes react-dom/client react-dom/server
react-dom/unstable_testing react-dom/profiling and react-dom/static

This update makes importing any of these client only entrypoints an
error
2024-04-08 15:37:06 -07:00
Josh Story
8436bcca62
[Fizz][Legacy] Remove renderToNodeStream (#28607)
Stacked on #28606 

renderToNodeStream has been deprecated since React 18 with a warning
indicating users should upgrade to renderToPipeableStream. This change
removes renderToNodeStream
2024-03-27 12:02:36 -07:00
Andrew Clark
5d1b15a4f0
Rename "shared subset" to "server" (#27939)
The internal file ReactSharedSubset is what the `react` module resolves
to when imported from a Server Component environment. We gave it this
name because, originally, the idea was that Server Components can access
a subset of the APIs available on the client.

However, since then, we've also added APIs that can _only_ by accessed
on the server and not the client. In other words, it's no longer a
subset, it's a slightly different overlapping set.

So this commit renames ReactSharedSubet to ReactServer and updates all
the references. This does not affect the public API, only our internal
implementation.
2024-01-16 19:58:11 -05:00
Andrew Clark
2d2f2af29b
Restrict React DOM imports from Server Components (#27382)
Adds a separate entry point for the react-dom package when it's accessed
from a Server Component environment, using the "react-server" export
condition.

When you're inside a Server Component module, you won't be able to
import client-only APIs like useState. This applies to almost all React
DOM exports, except for Float ones like preload.
2023-09-15 14:53:19 -04:00
Sebastian Markbåge
2c2bdd0ffe
[Fizz] Move /static build into /server builds (#27327)
This joins the static (prerender) builds with the server builds but
doesn't change the public entry points.

The idea of two separate bundles is that we'd have a specialized build
for Fizz just for the prerender that could do a lot more. However, in
practice the code is implemented with a dynamic check so it's in both.
It's also not a lot of code.

At the same time if you do have a set up that includes both the
prerender and the render in the same build output, this just doubles the
server bundle size for no reason.

So we might as well merge them into one build. However, I don't expose
the `prerender` from `/server`. Instead it's just exposed from the
public `/static` entry point. This leaves us with the option to go back
to separate builds later if it diverges more in the future.
2023-09-05 15:55:20 -04:00
Sebastian Markbåge
b70a0d7022
[Fizz] Track postponed holes in the prerender pass (#27317)
This is basically the implementation for the prerender pass.

Instead of forking basically the whole implementation for prerender, I
just add a conditional field on the request. If it's `null` it behaves
like before. If it's non-`null` then instead of triggering client
rendered boundaries it triggers those into a "postponed" state which is
basically just a variant of "pending". It's supposed to be filled in
later.

It also builds up a serializable tree of which path can be followed to
find the holes. This is basically a reverse `KeyPath` tree.

It is unfortunate that this approach adds more code to the regular Fizz
builds but in practice. It seems like this side is not going to add much
code and we might instead just want to merge the builds so that it's
smaller when you have `prerender` and `resume` in the same bundle -
which I think will be common in practice.

This just implements the prerender side, and not the resume side, which
is why the tests have a TODO. That's in a follow up PR.
2023-08-31 12:23:26 -04:00
Sebastian Markbåge
31034b6de7
[Fizz] Split ResponseState/Resources into RenderState/ResumableState (#27268)
This exposes a `resume()` API to go with the `prerender()` (only in
experimental). It doesn't work yet since we don't yet emit the postponed
state so not yet tested.

The main thing this does is rename ResponseState->RenderState and
Resources->ResumableState. We separated out resources into a separate
concept preemptively since it seemed like separate enough but probably
doesn't warrant being a separate concept. The result is that we have a
per RenderState in the Config which is really just temporary state and
things that must be flushed completely in the prerender. Most things
should be ResumableState.

Most options are specified in the `prerender()` and transferred into the
`resume()` but certain options that are unique per request can't be.
Notably `nonce` is special. This means that bootstrap scripts and
external runtime can't use `nonce` in this mode. They need to have a CSP
configured to deal with external scripts, but not inline.

We need to be able to restore state of things that we've already emitted
in the prerender. We could have separate snapshot/restore methods that
does this work when it happens but that means we have to explicitly do
that work. This design is trying to keep to the principle that we just
work with resumable data structures instead so that we're designing for
it with every feature. It also makes restoring faster since it's just
straight into the data structure.

This is not yet a serializable format. That can be done in a follow up.

We also need to vet that each step makes sense. Notably stylesToHoist is
a bit unclear how it'll work.
2023-08-22 15:21:36 -04:00
Sebastian Markbåge
01a0c4e12c
Add Edge Server Builds for workerd / edge-light (#26116)
We currently abuse the browser builds for Web streams derived
environments. We already have a special build for Bun but we should also
have one for [other "edge"
runtimes](https://runtime-keys.proposal.wintercg.org/) so that we can
maximally take advantage of the APIs that exist on each platform.

In practice, we currently check for a global property called
`AsyncLocalStorage` in the server browser builds which we shouldn't
really do since browsers likely won't ever have it. Additionally, this
should probably move to an import which we can't add to actual browser
builds where that will be an invalid import. So it has to be a separate
build. That's not done yet in this PR but Vercel will follow
Cloudflare's lead here.

The `deno` key still points to the browser build since there's no
AsyncLocalStorage there but it could use this same or a custom build if
support is added.
2023-02-07 15:10:01 -05:00
Jan Kassens
6b30832666
Upgrade prettier (#26081)
The old version of prettier we were using didn't support the Flow syntax
to access properties in a type using `SomeType['prop']`. This updates
`prettier` and `rollup-plugin-prettier` to the latest versions.

I added the prettier config `arrowParens: "avoid"` to reduce the diff
size as the default has changed in Prettier 2.0. The largest amount of
changes comes from function expressions now having a space. This doesn't
have an option to preserve the old behavior, so we have to update this.
2023-01-31 08:25:05 -05:00
Colin McDonnell
56ffca8b9e
Add Bun streaming server renderer (#25597)
Add support for Bun server renderer
2022-11-17 13:15:56 -08:00
Josh Story
aa9988e5e6
Server render fork for react-dom (#25436)
Publish an aliasable entry for `react-dom` top level package exports for use in server environments. This is a stub containing only the exports that we expect to retain in the top level once 19 is released
2022-10-10 11:06:22 -07:00
Sebastian Markbåge
0f216ae31d
Add entry points for "static" server rendering passes (#24752)
This will be used to add optimizations for static server rendering.
2022-06-18 22:34:31 -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
Sebastian Markbåge
a3bde7974c
Exclude react-dom/unstable_testing entry point from stable releases (#23258)
* 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
2022-02-08 23:12:31 -05:00
Brian Vaughn
aa19d569b2
Add test selectors to experimental build (#22760)
This change adds a new "react-dom/unstable_testing" entry point but I believe its contents will exactly match "react-dom/index" for the stable build. (The experimental build will have the added new selector APIs.)
2021-11-16 16:27:10 -05:00
Sebastian Markbåge
579c008a75
[Fizz/Flight] pipeToNodeWritable(..., writable).startWriting() -> renderToPipeableStream(...).pipe(writable) (#22450)
* Rename pipeToNodeWritable to renderToNodePipe

* Add startWriting API to Flight

We don't really need it in this case because there's way less reason to
delay the stream in Flight.

* Pass the destination to startWriting instead of renderToNode

* Rename startWriting to pipe

This mirrors the ReadableStream API in Node

* Error codes

* Rename to renderToPipeableStream

This mimics the renderToReadableStream API for the browser.
2021-10-06 00:31:06 -04:00
Sebastian Markbåge
9212d994ba
Merge /unstable-fizz entry point into /server (#21684) 2021-06-14 18:37:44 -07:00
Sebastian Markbåge
9343f87203
Use the server src files as entry points for the builds/tests (#21683)
* Use the server src files as entry points for the builds/tests

We need one top level entry point to target two builds so we can't have
the top level one be the entry point for the builds.

* Same thing but with the modern entry point
2021-06-14 16:23:19 -07:00
Nicolas Gallagher
96203240d3
ReactDOM: remove unstable-native-dependencies bundle (#18483)
This is only used by react-native-web and will be replaced by a user-space
implementation. See: https://github.com/necolas/react-native-web/issues/1568
2020-04-18 15:40:13 -07:00
Sunil Pai
3e9251d605
make testing builds for React/ReactDOM (#17915)
This PR introduces adds `react/testing` and `react-dom/testing`.
- changes infra to generate these builds
- exports act on ReactDOM in these testing builds
- uses the new test builds in fixtures/dom

In the next PR -

- I'll use the new builds for all our own tests
- I'll replace usages of TestUtils.act with ReactDOM.act.
2020-02-03 23:31:31 +00:00
Sebastian Markbåge
39dbb14da3
[Flight] Move Flight DOM to a Webpack Specific Package (#17372)
* Move Flight DOM to Webpack Specific Packagee

We'll have Webpack specific coupling so we need to ensure that it can be
versioned separately from various Webpack versions. We'll also have builds
for other bundlers in the future.

* Move to peerDep

* Move DOM Flight Tests

* Merge ReactFlightIntegration into ReactFlightDOM

This was an integration test. We can add to it.

* Fix fixture paths
2019-11-15 11:46:07 -08:00
Sebastian Markbåge
f4e974d26e
Add Experimental Flight Infrastructure (#16398)
* Add Flight Build and Unify HostFormat Config between Flight and Fizz

* Add basic resolution of models

* Add basic Flight fixture

Demonstrates the streaming protocol.

* Rename to flight-server to distinguish from the client parts

* Add Flight Client package and entry point

* Fix fixture
2019-10-29 14:45:47 -07:00
Sebastian Markbåge
1d25aa5787
[Fizz] New Server Rendering Infra (#14144)
* [Fizz] Add Flow/Jest/Rollup build infra

Add a new package for react-stream which allows for custom server renderer
outputs. I picked the name because it's a reasonable name but also
because the npm name is currently owned by a friend of the project.

The react-dom build has its own inlined server renderer under the
name `react-dom/fizz`.

There is also a noop renderer to be used for testing. At some point
we might add a public one to test-renderer but for now I don't want to have
to think about public API design for the tests.

* Add FormatConfig too

We need to separate the format (DOM, React Native, etc) from the host
running the server (Node, Browser, etc).

* Basic wiring between Node, Noop and DOM configs

The Node DOM API is pipeToNodeStream which accepts a writable stream.

* Merge host and format config in dynamic react-stream entry point

Simpler API this way but also avoids having to fork the wrapper config.

Fixes noop builds.

* Add setImmediate/Buffer globals to lint config

Used by the server renderer

* Properly include fizz.node.js

Also use forwarding to it from fizz.js in builds so that tests covers
this.

* Make react-stream private since we're not ready to publish

or even name it yet

* Rename Renderer -> Streamer

* Prefix react-dom/fizz with react-dom/unstable-fizz

* Add Fizz Browser host config

This lets Fizz render to WHATWG streams. E.g. for rendering in a
Service Worker.

I added react-dom/unstable-fizz.browser as the entry point for this.

Since we now have two configurations of DOM. I had to add another
inlinedHostConfigs configuration called `dom-browser`. The reconciler
treats this configuration the same as `dom`. For stream it checks
against the ReactFizzHostConfigBrowser instead of the Node one.

* Add Fizz Browser Fixture

This is for testing server rendering - on the client.

* Lower version number to detach it from react-reconciler version
2018-11-30 11:38:22 -08:00
Brian Vaughn
4e744be6ee
Added react-dom/profiling entry point to NPM package (#13570) 2018-09-05 11:16:43 -07:00
Dan Abramov
1eed302d34 Drop Haste (#11303)
* Use relative paths in packages/react

* Use relative paths in packages/react-art

* Use relative paths in packages/react-cs

* Use relative paths in other packages

* Fix as many issues as I can

This uncovered an interesting problem where ./b from package/src/a would resolve to a different instantiation of package/src/b in Jest.

Either this is a showstopper or we can solve it by completely fobbidding remaining /src/.

* Fix all tests

It seems we can't use relative requires in tests anymore. Otherwise Jest becomes confused between real file and symlink.
https://github.com/facebook/jest/issues/3830

This seems bad... Except that we already *don't* want people to create tests that import individual source files.
All existing cases of us doing so are actually TODOs waiting to be fixed.

So perhaps this requirement isn't too bad because it makes bad code looks bad.

Of course, if we go with this, we'll have to lint against relative requires in tests.
It also makes moving things more painful.

* Prettier

* Remove @providesModule

* Fix remaining Haste imports I missed earlier

* Fix up paths to reflect new flat structure

* Fix Flow

* Fix CJS and UMD builds

* Fix FB bundles

* Fix RN bundles

* Prettier

* Fix lint

* Fix warning printing and error codes

* Fix buggy return

* Fix lint and Flow

* Use Yarn on CI

* Unbreak Jest

* Fix lint

* Fix aliased originals getting included in DEV

Shouldn't affect correctness (they were ignored) but fixes DEV size regression.

* Record sizes

* Fix weird version in package.json

* Tweak bundle labels

* Get rid of output option by introducing react-dom/server.node

* Reconciler should depend on prop-types

* Update sizes last time
2017-10-25 02:55:00 +03:00
Dan Abramov
d9c1dbd617 Use Yarn Workspaces (#11252)
* Enable Yarn workspaces for packages/*

* Move src/isomorphic/* into packages/react/src/*

* Create index.js stubs for all packages in packages/*

This makes the test pass again, but breaks the build because npm/ folders aren't used yet.
I'm not sure if we'll keep this structure--I'll just keep working and fix the build after it settles down.

* Put FB entry point for react-dom into packages/*

* Move src/renderers/testing/* into packages/react-test-renderer/src/*

Note that this is currently broken because Jest ignores node_modules,
and so Yarn linking makes Jest skip React source when transforming.

* Remove src/node_modules

It is now unnecessary. Some tests fail though.

* Add a hacky workaround for Jest/Workspaces issue

Jest sees node_modules and thinks it's third party code.

This is a hacky way to teach Jest to still transform anything in node_modules/react*
if it resolves outside of node_modules (such as to our packages/*) folder.

I'm not very happy with this and we should revisit.

* Add a fake react-native package

* Move src/renderers/art/* into packages/react-art/src/*

* Move src/renderers/noop/* into packages/react-noop-renderer/src/*

* Move src/renderers/dom/* into packages/react-dom/src/*

* Move src/renderers/shared/fiber/* into packages/react-reconciler/src/*

* Move DOM/reconciler tests I previously forgot to move

* Move src/renderers/native-*/* into packages/react-native-*/src/*

* Move shared code into packages/shared

It's not super clear how to organize this properly yet.

* Add back files that somehow got lost

* Fix the build

* Prettier

* Add missing license headers

* Fix an issue that caused mocks to get included into build

* Update other references to src/

* Re-run Prettier

* Fix lint

* Fix weird Flow violation

I didn't change this file but Flow started complaining.
Caleb said this annotation was unnecessarily using $Abstract though so I removed it.

* Update sizes

* Fix stats script

* Fix packaging fixtures

Use file: instead of NODE_PATH since NODE_PATH.
NODE_PATH trick only worked because we had no react/react-dom in root node_modules, but now we do.

file: dependency only works as I expect in Yarn, so I moved the packaging fixtures to use Yarn and committed lockfiles.
Verified that the page shows up.

* Fix art fixture

* Fix reconciler fixture

* Fix SSR fixture

* Rename native packages
2017-10-19 00:22:21 +01:00