stacked on https://github.com/facebook/react/pull/25569
On the client noscript already never renders children so no resources
will be extracted from this context. On the server we now track if we
are in a noscript context and turn off Resource semantics in this scope
there are a few bugs where dom representations from SSR aren't
identified as Resources when they should be.
There are 3 semantics
Resource -> hoist to head, deduping, etc...
hydratable Component -> SSR'd and hydrated in place
non-hydratable Component -> never SSR'd, never hydrated, always inserted
on the client
this last category is small
(non stylesheet) links with onLoad and/or onError
async scripts with onLoad and/or onError
The reason we have this distinction for now is we need every SSR'd async
script to be assumable to be a Resource. we don't currently encode
onLoad on the server and so we couldn't otherwise tell if an async
script is a Resource or is an async script with an onLoad which would
not be a resource. To avoid this ambiguity we never emit the scripts in
SSR and assume they need to be inserted on the client.
We can explore changes to these semantics in the future or possibly
encode some identifier when we want to opt out of resource semantics but
still SSR the link or script.
keys off `target` and `href`.
prepends on insertion similar to title.
only flushes on the server in the shell (should probably add a warning
if there are any to flush in a boundary)
Adds some clarifying warnings when you render a component that is almost
a resource but isn't and the element was rendered outside the main
document tree (outside of `<body>` or `<head>`
replaces: https://github.com/facebook/react/pull/25535
This takes a more huerstic based approach with no new conditionals on
the hot path of fizz rendering.
If float is enabled
* title and script can only have simple children
* if non-simple children are found they will be ignored
* title and script are pushed in a single unit during pushStartInstance
including their children and closing tags
If float is not enabled
* the original pushing behaviors are in place and you can have complex
children but you will get warnings
escapeTextForBrowser accepts any type so flow did not identify that we
were escaping a Chunk rather than a string. It's tricky because we
sometimes want to be able to escape non strings.
I've also updated the types for `Chunk` and `escapeTextForBrowser`
so that we should be able to catch this statically in the future.
The reason this did not show up in tests is almost all of our tests of
float (the areas affected by transpositions) are tested using the Node
runtime where a chunk type is a string. It may be wise to run these
tests in every runtime in the future or at least make sure there is
broad representation of resources in each specific runtime test suite.
stacked on https://github.com/facebook/react/pull/25514
This PR adds support for any type of Link as long as it has a string rel
and href and does not include an onLoad or onError property.
The semantics for generic link resources matches other head resources,
they will be inserted and removed as their ref counts go positive and
back to zero.
Keys are based on rel, href, sizes, and media.
on the server preconnect and prefetch-dns are privileged and will emit
near the start of the stream.
Stacked on #25508
This PR adds meta tags as a resource type.
metas are classified in the following priority
1. charset
2. http-equiv
3. property
4. name
5. itemprop
when using property, there is special logic for og type properties where
a `property="og:image:height"` following a `property="og:image"` will
inherit the key of the previous tag. this relies on timing effects to
stay consistent so when mounting new metas it is important that if
structured properties are being used all members of a structure mount
together. This is similarly true for arrays where the implicit
sequential order defines the array structure. if you need an array you
need to mount all array members in the same pass.
With the `react-dom/server-rendering-stub` you can import `react-dom` in
RSC so that you can call `preload` and `preinit` but if you don't alias
it, then requiring it breaks because we React.Component which doesn't
exist in the react subset.
Adds a category of Resources of type `head` which will be used to track
the tags that go into the <head>
Currently only implements for `<title>`.
titles are keyed off their textContent so each time the title changes a
new resource will be created. Currently insertion is done by prepending
in the <head>. The argument here is that the newest title should "win"
if there are multiple rendered. This also helps when a navigation or
update causes a server rendered title to hang around but it is not the
most recent one.
* Facebook -> Meta in copyright
rg --files | xargs sed -i 's#Copyright (c) Facebook, Inc. and its affiliates.#Copyright (c) Meta Platforms, Inc. and affiliates.#g'
* Manual tweaks
* Add feature flag for external Fizz runtime
Only enabled for www for now
* Add option to load Fizz runtime from external file
When unstable_externalRuntimeSrc is provided, React will inject a script
tag that points to the provided URL.
Then, instead of emitting inline scripts, the Fizz stream will emit
HTML nodes with data attributes that encode the instructions. The
external runtime will detect these with a mutation observer and
translate them into runtime commands. This part isn't implemented in
this PR, though — all this does is set up the option to use
an external runtime, and inject the script tag.
The external runtime is injected at the same time as bootstrap scripts.
* float enhance!!!
Support preinit as script
Support resources from async scripts
Support saving the precedence place when rendering the shell
There was a significant change to the flushing order of resources which follows the general principal of...
1. stuff that blocks display
2. stuff that we know will be used
3. stuff that was explicitly preloaded
As a consequence if you preinit a style now it won't automatically flush in the shell unless you actually depend on it in your tree. To avoid races with precedence order we now emit a tag that saves the place amongst the precedence hierarchy so late insertions still end up where they were intended
There is also a novel hydration pathway for certain tags. If you render an async script with an onLoad or onError it will always treat it like an insertion rather than a hydration.
* restore preinit style flushing behavior and nits
Fixes a bug that happens when you suspend in the shell (the part of the
tree that is not wrapped in a Suspense boundary) during a
discrete update.
There were two underyling issues. One was just a mistake:
RootDidNotComplete needs to be handled in both renderRootConcurrent and
renderRootSync, but it was only handled in renderRootConcurrent. I did
it this way because I thought this path was unreachable during a sync
update, but I neglected to consider that renderRootSync is sometimes
called for non-concurrent lanes, like when recovering from an error, or
patching up a mutation to an external store.
After I fixed that oversight, the other issue is that we intentionally
error if the shell suspends during a sync update. The idea was that you
should either wrap the tree in a Suspense boundary, or you should mark
the update as a transition to allow React to suspend.
However, this did not take into account selective hydration, which can
force a sync render before anything has even committed. There's no way
in that case to wrap the update in startTransition.
Our solution for now is to remove the error that happens when you
suspend in the shell during a sync update — even for discrete updates.
We will likely revisit this in the future. One appealing possibility is
to commit the whole root in an inert state, as if it were a hidden
Offscreen tree.
Co-authored-by: Sebastian Markbåge <sebastian@calyptus.eu>
Co-authored-by: Sebastian Markbåge <sebastian@calyptus.eu>
* Scaffolding for react-dom/unstable_external-server-runtime
Implements a new bundle type for in our build config called
BROWSER_SCRIPT. This is intended for scripts that get delivered straight
to the browser without needing to be processed by a bundler. (And also
doesn't include any extra UMD crap.)
Right now there's only a single use case so I didn't stress about making
it general purpose.
The use case is: a script that loads the Fizz browser runtime, and sets
up a MutationObserver to receive instructions as HTML streams in. This
will be an alternative option to the default Fizz behavior of sending
the runtime down as inline script tags, to accommodate environments
where inline script tags are not allowed.
There's no development version of this bundle because it doesn't contain
any warnings or run any user code.
None of the actual implementation is in this PR; it just sets up the
build infra.
Co-authored-by: Mofei Zhang <feifei0@fb.com>
* Set BUNDLE_SCRIPT's GCC output format to ES5
This removes the automatic 'use strict' directive, which we don't need.
Co-authored-by: Mofei Zhang <feifei0@fb.com>
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
* track resources in different roots separately
* flow types
* add test demonstrating portals deep into shadowRoots
* revert hostcontext changes
* lints
* funge style cache key a la ReactDOMComponentTree
* hide hacks in componentTree
- method unbinding is no longer supported in Flow for soundness, this added a bunch of suppressions
- Flow now prevents objects to be supertypes of interfaces/classes
ghstack-source-id: d7749cbad8
Pull Request resolved: https://github.com/facebook/react/pull/25412
This was a large upgrade that removed "classic mode" and made "types first" the only option.
Most of the needed changes have been done in previous PRs, this just fixes up the last few instances.
ghstack-source-id: 9612d95ba4
Pull Request resolved: https://github.com/facebook/react/pull/25408
* [Fizz/Float] Float for stylesheet resources
This commit implements Float in Fizz and on the Client. The initial set of supported APIs is roughly
1. Convert certain stylesheets into style Resources when opting in with precedence prop
2. Emit preloads for stylesheets and explicit preload tags
3. Dedupe all Resources by href
4. Implement ReactDOM.preload() to allow for imperative preloading
5. Implement ReactDOM.preinit() to allow for imperative preinitialization
Currently supports
1. style Resources (link rel "stylesheet")
2. font Resources (preload as "font")
later updates will include support for scripts and modules
This lets us share it with react-server-dom-webpack while still having a
dependency on react-dom. It also makes somewhat sense from a bundling
perspective since react-dom is an external to itself.
add more accurate end time for transitions and update host configs with `requestPostPaintCallback` function and move post paint logic to another module and use it in the work loop
This update range includes:
- `types_first` ([blog](https://flow.org/en/docs/lang/types-first/), all exports need annotated types) is default. I disabled this for now to make that change incremental.
- Generics that escape the scope they are defined in are an error. I fixed some with explicit type annotations and some are suppressed that I didn't easily figure out.
Follow up to #25084 and #25207. Implements experimental_use(promise) API
in the SSR runtime (Fizz).
This is largely a copy-paste of the Flight implementation. I have
intentionally tried to keep both as close as possible.
Implement basic support for "Resources". In the context of this commit, the only thing that is currently a Resource are
<link rel="stylesheet" precedence="some-value" ...>
Resources can be rendered anywhere in the react tree, even outside of normal parenting rules, for instance you can render a resource before you have rendered the <html><head> tags for your application. In the stream we reorder this so the browser always receives valid HTML and resources are emitted either in place (normal circumstances) or at the top of the <head> (when you render them above or before the <head> in your react tree)
On the client, resources opt into an entirely different hydration path. Instead of matching the location within the Document these resources are queried for in the entire document. It is an error to have more than one resource with the same href attribute.
The use of precedence here as an opt-in signal for resourcifying the link is in preparation for a more complete Resource implementation which will dedupe resource references (multiple will be valid), hoist to the appropriate container (body, head, or elsewhere), order (according to precedence) and Suspend boundaries that depend on them. More details will come in the coming weeks on this plan.
This feature is gated by an experimental flag and will only be made available in experimental builds until some future time.