The forking for `shared/ReactFeatureFlags` doesn't work in the console
patches. Since they're already forked, we can import the internal
ReactFeatureFlags files directly.
Would have caught this in testing a PR sync, but the PR syncs are broken
right now.
#31787 introduces an experimental scheduler flag:
`enableAlwaysYieldScheduler`, which is turned off for www. There wasn't
a SchedulerFeatureFlags fork for native-fb, so the experimental change
was enabled in the Scheduler-dev build there which causes test failures
and is blocking the sync.
#31805 introduces another scheduler flag `enableRequestPaint`, which is
set as a `__VARIANT__` on www. I've set this to `true` here to preserve
the existing behavior. We can follow up with dynamic flags for native-fb
after unblocking the sync.
This adds a new `react-server-dom-parcel-package`, which is an RSC
integration for the Parcel bundler. It is mostly copied from the
existing webpack/turbopack integrations, with some changes to utilize
Parcel runtime APIs for loading and executing bundles/modules.
See https://github.com/parcel-bundler/parcel/pull/10043 for the Parcel
side of this, which includes the plugin needed to generate client and
server references. https://github.com/parcel-bundler/rsc-examples also
includes examples of various ways to use RSCs with Parcel.
Differences from other integrations:
* Client and server modules are all part of the same graph, and we use
Parcel's
[environments](https://parceljs.org/plugin-system/transformer/#the-environment)
to distinguish them. The server is the Parcel build entry point, and it
imports and renders server components in route handlers. When a `"use
client"` directive is seen, the environment changes and Parcel creates a
new client bundle for the page, combining all client modules together.
CSS from both client and server components are also combined
automatically.
* There is no separate manifest file that needs to be passed around by
the user. A [Runtime](https://parceljs.org/plugin-system/runtime/)
plugin injects client and server references as needed into the relevant
bundles, and registers server action ids using `react-server-dom-parcel`
automatically.
* A special `<Resources>` component is also generated by Parcel to
render the `<script>` and `<link rel="stylesheet">` elements needed for
a page, using the relevant info from the bundle graph.
Note: I've already published a 0.0.x version of this package to npm for
testing purposes but happy to add whoever needs access to it as well.
### Questions
* How to test this in the React repo. I'll have integration tests in
Parcel, but setting up all the different mocks and environments to
simulate that here seems challenging. I could try to copy how
Webpack/Turbopack do it but it's a bit different.
* Where to put TypeScript types. Right now I have some ambient types in
my [example
repo](https://github.com/parcel-bundler/rsc-examples/blob/main/types.d.ts)
but it would be nice for users not to copy and paste these. Can I
include them in the package or do they need to maintained separately in
definitelytyped? I would really prefer not to have to maintain code in
three different repos ideally.
---------
Co-authored-by: Sebastian Markbage <sebastian@calyptus.eu>
## Summary
I'm working to get the main `react-native` package parsable by modern
Flow tooling (both `flow-bundler`, `flow-api-translator`), and one
blocker is legacy `module.exports` syntax. This diff updates files which
are [synced to
`react-native`](https://github.com/facebook/react-native/tree/main/packages/react-native/Libraries/Renderer/shims)
from this repo.
## How did you test this change?
Files were pasted into `react-native-github` under fbsource, where Flow
validates ✅.
Backs out the 2 related commits:
-
f8f6e1a21a
-
6c0f37f94b
Since I only realized when syncing that we need the version of `react`
and the legacy renderer to match.
While I investigate if there's anything we can do to work around that
while preserving the legacy renderer, this unblocks the sync.
We don't actually want the source mapped version of `.stack` from errors
because that would cause us to not be able to associate it with a source
map in the UIs that need it. The strategy in browsers is more correct
where the display is responsible for source maps.
That's why we disable any custom `prepareStackTrace` like the ones added
by `source-map`. We reset it to `undefined`.
However, when running node with `--enable-source-maps` the default for
`prepareStackTrace` which is a V8 feature (but may exist elsewhere too
like Bun) is a source mapped version of the stack. In those environments
we need to reset it to a default implementation that doesn't apply
source maps.
We already did this in Flight using the `ReactFlightStackConfigV8.js`
config. However, we need this more generally in the
`shared/ReactComponentStackFrame` implementation.
We could always set it to the default implementation instead of
`undefined` but that's unnecessary code in browser builds and it might
lead to slightly different results. For safety and code size, this PR
does it with a fork instead.
All builds specific to `node` or `edge` (or `markup` which is a server
feature) gets the default implementation where as everything else (e.g.
browsers) get `undefined` since it's expected that this is not source
mapped. We don't have to do anything about the equivalent in React
DevTools since React DevTools doesn't run on the server.
## Summary
Builds `react-dom` for React Native so that it also populates the
`builds/facebook-fbsource` branch.
**NOTE:** For Meta employees, D61354219 is the internal integration.
## How did you test this change?
```
$ yarn build
…
$ ls build/facebook-react-native/react-dom/cjs
ReactDOM-dev.js ReactDOM-prod.js ReactDOM-profiling.js
```
## Summary
When a view config can not be found, it currently errors with
`TypeError: Cannot read property 'bubblingEventTypes' of null`. Instead
invariant at the correct location and prevent further processing of the
null viewConfig to improve the error logged.
## How did you test this change?
Build and run RN playground app referencing an invalid native view
through `requireNativeComponent`.
The unbundled form is just a way to show case a prototype for how an
unbundled version of RSC can work. It's not really intended for every
bundler combination to provide such a configuration.
There's no configuration of Turbopack that supports this mode atm and
possibly never will be since it's more of an integrated server/client
experience.
This removes the unbundled form and node register/loaders from the
turbopack build.
Follow up to #30741.
This is just for the reference Webpack implementation.
If there is a source map associated with a Node ESM loader, we generate
new source map entries for every `registerServerReference` call.
To avoid messing too much with it, this doesn't rewrite the original
mappings. It just reads them while finding each of the exports in the
original mappings. We need to read all since whatever we append at the
end is relative. Then we just generate new appended entries at the end.
For the location I picked the location of the local name identifier.
Since that's the name of the function and that gives us a source map
name index. It means it jumps to the name rather than the beginning of
the function declaration. It could be made more clever like finding a
local function definition if it is reexported. We could also point to
the line/column of the function declaration rather than the identifier
but point to the name index of the identifier name.
Now jumping to definition works in the fixture.
<img width="574" alt="Screenshot 2024-08-20 at 2 49 07 PM"
src="https://github.com/user-attachments/assets/7710f0e6-2cee-4aad-8d4c-ae985f8289eb">
Unfortunately this technique doesn't seem to work in Firefox nor Safari.
They don't apply the source map for jumping to the definition.
This commit updates the file locations and bulid configurations for
flight in preparation for new static entrypoints. This follows a
structure similar to Fizz which has a unified build but exports methods
from different top level entrypoints. This PR doesn't actually add the
new top level entrypoints however, that will arrive in a later update.
https://github.com/facebook/react/pull/30422 broke existing build
shortcuts.
Revert the usage of `names` (`_`) and `type` args.
`yarn build-for-devtools` / `yarn build-for-devtools-dev` / `yarn
build-for-devtools-prod` should all work again.
Moved the bundleType documentation into description so they can be fuzzy
matched. But a build like `yarn build --type FB_WWW_PROD` still works
when matched exactly.
There's probably a better way to document the positional `names` arg in
the `--help` command, but didn't see it when browsing the yargs docs so
let's just fix the existing builds for now.
Now:
```
% yarn build --help
yarn run v1.22.19
$ node ./scripts/rollup/build-all-release-channels.js --help
Options:
--help Show help [boolean]
--version Show version number [boolean]
--releaseChannel, -r Build the given release channel. [string] [choices: "experimental", "stable"]
--index, -i Worker id. [number]
--total, -t Total number of workers. [number]
--ci Run tests in CI [choices: "circleci", "github"]
--type Build the given bundle type. (NODE_ES2015,ESM_DEV,ESM_PROD,NODE_DEV,NODE_PROD,NODE_PROFILING,BUN_DEV,BUN_PROD,FB_WWW_DEV,FB_WWW_PROD,FB_WWW_PROFILING,RN_OSS_DE
V,RN_OSS_PROD,RN_OSS_PROFILING,RN_FB_DEV,RN_FB_PROD,RN_FB_PROFILING,BROWSER_SCRIPT) [string]
--pretty Force pretty output. [boolean]
--sync-fbsource Include to sync build to fbsource. [string]
--sync-www Include to sync build to www. [string]
--unsafe-partial Do not clean ./build first.
```
Improve command documentation and make it easier to build specific
bundle types
**Before**
```
% yarn build --help
yarn run v1.22.19
$ node ./scripts/rollup/build-all-release-channels.js --help
Options:
--help Show help [boolean]
--version Show version number [boolean]
--releaseChannel, -r Build the given release channel. [string] [choices: "experimental", "stable"]
--index, -i Worker id. [number]
--total, -t Total number of workers. [number]
--ci Run tests in CI [choices: "circleci", "github"]
✨ Done in 0.69s.
```
**After**
```
% yarn build --help
yarn run v1.22.19
$ node ./scripts/rollup/build-all-release-channels.js --help
Options:
--help Show help [boolean]
--version Show version number [boolean]
--releaseChannel, -r Build the given release channel. [string] [choices: "experimental", "stable"]
--index, -i Worker id. [number]
--total, -t Total number of workers. [number]
--bundle Build the given bundle type.
[choices: "NODE_ES2015", "ESM_DEV", "ESM_PROD", "NODE_DEV", "NODE_PROD", "NODE_PROFILING", "BUN_DEV", "BUN_PROD", "FB_WWW_DEV", "FB_WWW_PROD",
"FB_WWW_PROFILING", "RN_OSS_DEV", "RN_OSS_PROD", "RN_OSS_PROFILING", "RN_FB_DEV", "RN_FB_PROD", "RN_FB_PROFILING", "BROWSER_SCRIPT"]
--ci Run tests in CI [choices: "circleci", "github"]
--names Build for matched bundle names. Example: "react-test,index.js". [array]
--pretty Force pretty output. [boolean]
--sync-fbsource Include to sync build to fbsource. [string]
--sync-www Include to sync build to www. [string]
--unsafe-partial Do not clean ./build first. [boolean]
✨ Done in 0.61s.
```
Changes
- Use yargs to document existing options: `pretty`, `sync-fbsource`,
`sync-www`, `unsafe-partial`.
- Move `_` arg to `names` option for consistency with other options and
discoverability through yargs help
- Add `bundle` option in place of `argv.type` that allows choices of any
BundleType to be passed in directly.
Stacked on #30308.
This is now a noop module so we can stop applying the transform of
console.error using the Babel plugin in the mainline builds. I'm keeping
the transform for RN/WWW for now although it might be nice if the
transform moved into those systems as it gets synced instead of keeping
it upstream.
In jest tests we're already not running the forks for RN/WWW so we don't
need it at all there.
This avoids potential differences between Git versions.
Having a guarantee unique hash isn't neccessary as it's just
informational and we have the date in the version string as well.
We're removing this wrapper from the mainline but RN is still using
component stacks to filter out warnings.
This is unfortunate since it'll be hard to keep track of the interplay
with these, DevTools and how you're supposed to implement error dialogs
in userspace.
Even though the whole package is private right now. Once we publish it,
it'll likely be just the experimental channel first before upgrading to
stable.
This means it gets excluded from the built packages.
Follow up to #30105.
This supports `renderToMarkup` in a non-RSC environment (not the
`react-server` condition).
This is just a Fizz renderer but it errors at runtime when you use
state, effects or event handlers that would require hydration - like the
RSC version would. (Except RSC can give early errors too.)
To do this I have to move the `react-html` builds to a new `markup`
dimension out of the `dom-legacy` dimension so that we can configure
this differently from `renderToString`/`renderToStaticMarkup`.
Eventually that dimension can go away though if deprecated. That also
helps us avoid dynamic configuration and we can just compile in the
right configuration so the split helps anyway.
One consideration is that if a compiler strips out useEffects or inlines
initial state from useState, then it would not get called an the error
wouldn't happen. Therefore to preserve semantics, a compiler would need
to inject some call that can check the current renderer and whether it
should throw.
There is an argument that it could be useful to not error for these
because it's possible to write components that works with SSR but are
just optionally hydrated. However, there's also an argument that doing
that silently is too easy to lead to mistakes and it's better to error -
especially for the e-mail use case where you can't take it back but you
can replay a queue that had failures. There are other ways to
conditionally branch components intentionally. Besides if you want it to
be silent you can still use renderToString (or better yet
renderToReadableStream).
The primary mechanism is the RSC environment and the client-environment
is really the secondary one that's only there to support legacy
environments. So this also ensures parity with the primary environment.
Name of the package is tbd (straw: `react-html`). It's a new package
separate from `react-dom` though and can be used as a standalone package
- e.g. also from a React Native app.
```js
import {renderToMarkup} from '...';
const html = await renderToMarkup(<Component />);
```
The idea is that this is a helper for rendering HTML that is not
intended to be hydrated. It's primarily intended to support a subset of
HTML that can be used as embedding and not served as HTML documents from
HTTP. For example as e-mails or in RSS/Atom feeds or other
distributions. It's a successor to `renderToStaticMarkup`.
A few differences:
- This doesn't support "Client Components". It can only use the Server
Components subset. No useEffect, no useState etc. since it will never be
hydrated. Use of those are errors.
- You also can't pass Client References so you can't use components
marked with `"use client"`.
- Unlike `renderToStaticMarkup` this does support async so you can
suspend and use data from these components.
- Unlike `renderToReadableStream` this does not support streaming or
Suspense boundaries and any error rejects the promise. Since there's no
feasible way to "client render" or patch up the document.
- Form Actions are not supported since in an embedded environment
there's no place to post back to across versions. You can render plain
forms with fixed URLs though.
- You can't use any resource preloading like `preload()` from
`react-dom`.
## Implementation
This first version in this PR only supports Server Components since
that's the thing that doesn't have an existing API. Might add a Client
Components version later that errors.
We don't want to maintain a completely separate implementation for this
use case so this uses the `dom-legacy` build dimension to wire up a
build that encapsulates a Flight Server -> Flight Client -> Fizz stream
to render Server Components that then get SSR:ed.
There's no problem to use a Flight Client in a Server Component
environment since it's already supported for Server-to-Server. Both of
these use a bundler config that just errors for Client References though
since we don't need any bundling integration and this is just a
standalone package.
Running Fizz in a Server Component environment is a problem though
because it depends on "react" and it needs the client version.
Therefore, for this build we embed the client version of "react" shared
internals into the build. It doesn't need anything to be able to use
those APIs since you can't call the client APIs anyway.
One unfortunate thing though is that since Flight currently needs to go
to binary and back, we need TextEncoder/TextDecoder to be available but
this shouldn't really be necessary. Also since we use the legacy stream
config, large strings that use byteLengthOfChunk errors atm. This needs
to be fixed before shipping. I'm not sure what would be the best
layering though that isn't unnecessarily burdensome to maintain. Maybe
some kind of pass-through protocol that would also be useful in general
- e.g. when Fizz and Flight are in the same process.
---------
Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>
## Summary
Fix bundle type filtering logic to correctly handle array input in
argv.type and use some with includes for accurate filtering. This
addresses a TypeError encountered during yarn build-for-devtools-prod
and yarn build-for-devtools-dev commands.
## Motivation
The current implementation of the `shouldSkipBundle` function in
`scripts/rollup/build.js` has two issues:
1. **Incorrect array handling in
`parseRequestedNames`([#29613](https://github.com/facebook/react/issues/29613)):**
The function incorrectly wraps the `argv.type` value in an additional
array when it's already an array. This leads to a `TypeError:
names[i].split is not a function` when `parseRequestedNames` attempts to
split the nested array, as seen in this error message:
```
C:\Users\Administrator\Documents\새 폴더\react\scripts\rollup\build.js:76
let splitNames = names[i].split(',');
^
TypeError: names[i].split is not a function
```
This PR fixes this by correctly handling both string and array inputs in
`argv.type`:
```diff
- const requestedBundleTypes = argv.type
- ? parseRequestedNames([argv.type], 'uppercase')
+ const argvType = Array.isArray(argv.type) ? argv.type : [argv.type];
+ const requestedBundleTypes = argv.type
+ ? parseRequestedNames(argvType, 'uppercase')
```
2. **Inaccurate filtering logic in
`shouldSkipBundle`([#29614](https://github.com/facebook/react/issues/29614)):**
The function uses `Array.prototype.every` with `indexOf` to check if
**all** requested bundle types are missing in the current bundle type.
However, when multiple bundle types are requested (e.g., `['NODE',
'NODE_DEV']`), the function should skip a bundle only if **none** of the
requested types are present. The current implementation incorrectly
allows bundles that match any of the requested types.
To illustrate, consider the following example output:
```
requestedBundleTypes [ 'NODE', 'NODE_DEV' ]
bundleType NODE_DEV
isAskingForDifferentType false
requestedBundleTypes [ 'NODE', 'NODE_DEV' ]
bundleType NODE_PROD
isAskingForDifferentType false // Incorrect behavior
```
In this case, even though the bundle type is `NODE_PROD` and doesn't
include `NODE_DEV`, the bundle is not skipped due to the incorrect
logic.
This PR fixes this by replacing `every` with `some` and using `includes`
for a more accurate check:
```diff
- const isAskingForDifferentType = requestedBundleTypes.every(
- requestedType => bundleType.indexOf(requestedType) === -1
- );
+ const isAskingForDifferentType = requestedBundleTypes.some(
+ requestedType => !bundleType.includes(requestedType)
+ );
```
This ensures that the bundle is skipped only if **none** of the
requested types are found in the `bundleType`.
This PR addresses both of these issues to ensure correct bundle type
filtering in various build scenarios.
## How did you test this change?
1. **Verification of `requestedBundleTypes` usage in
`shouldSkipBundle`:**
* I manually tested the following scenarios:
* `yarn build`: Verified that `requestedBundleTypes` remains an empty
array, as expected.
* `yarn build-for-devtools`: Confirmed that `requestedBundleTypes` is
correctly set to `['NODE']`, as in the original implementation.
* `yarn build-for-devtools-dev`: This previously failed due to the
error. After the fix, I confirmed that `requestedBundleTypes` is now
correctly passed as `['NODE', 'NODE_DEV']`.
2. **Debugging of filtering logic in `shouldSkipBundle`:**
* I added the following logging statements to the `shouldSkipBundle`
function to observe its behavior during the build process:
```javascript
console.log('requestedBundleTypes', requestedBundleTypes);
console.log('bundleType', bundleType);
console.log('isAskingForDifferentType', isAskingForDifferentType);
```
* By analyzing the log output, I confirmed that the filtering logic now
correctly identifies when a bundle should be skipped based on the
requested types. This allowed me to verify that the fix enables building
specific target bundles as intended.
Only with the enableOwnerStacks flag (which is not on in www).
This is a new DEV-only API to be able to implement what we do for
console.error in user space.
This API does not actually include the current stack that you'd get from
`new Error().stack`. That you'd have to add yourself.
This adds the ability to have conditional development exports because we
plan on eventually having separate ESM builds that use the "development"
or "production" export conditions.
NOTE: This removes the export of `act` from `react` in prod (as opposed
to a function that throws) - inline with what we do with other
conditional exports.
## Overview
Reverts https://github.com/facebook/react/pull/26616 and implements the
suggested way instead.
This change in #26616 broken the internal sync command, which now
results in duplicated `@generated` headers. It also makes it harder to
detect changes during the diff train sync. Instead, we will check for
changes, and if there are changes sign the files and commit them to the
sync branch.
## Strategy
The new sync strategy accounts for the generated headers during the
sync:
- **Revert Version**: Revert the version strings
- **Revert @generated**: Re-sign the files (will be the same hash as
before if unchanged)
- **Check**: Check if there are changes **if not, skip**
- **Re-apply Version**: Now add back the new version string
- **Re-sign @generated**: And re-generate the headers
Then commit to branch. This ensures that if there are no changes, we'll
skip.
---------
Co-authored-by: Timothy Yung <yungsters@gmail.com>
The goal is to improve speed of the development by inlining and DCE
unused branches.
We have the ability to preserve some variable names and pretty print in
the production version so might as well do the same with DEV.
Use some clever git diffing to ignore lines that only change the
`@generated` header. We can't do this for the version string because the
version string can be embedded in lines with other changes, but this
header is always on one line.
RC releases are a special kind of prerelease build because unlike
canaries we shouldn't publish new RCs from any commit on `main`, only
when we intentionally bump the RC number. But they are still prerelases
— like canary and experimental releases, they should use exact version
numbers in their dependencies (no ^).
We only need to generate these builds during the RC phase, i.e. when the
canary channel label is set to "rc".
Example of resulting package.json output:
```json
{
"name": "react-dom",
"version": "19.0.0-rc.0",
"dependencies": {
"scheduler": "0.25.0-rc.0"
},
"peerDependencies": {
"react": "19.0.0-rc.0"
}
}
```
https://react-builds.vercel.app/prs/29736/files/oss-stable-rc/react-dom/package.json
Requires https://github.com/facebook/react/pull/29706
The strategy here is to:
- Checkout the builds/facebook-www branch
- Read the current sync'd VERSION
- Checkout out main and sync new build
- sed/{new version string}/{old version string}
- Run git status, skip sync if clean
- Otherwise, sed/{old version string}/{new version string} and push
commit
This means that:
- We're using the real version strings from the builds
- We are checking the last commit on the branch for the real last
version
- We're skipping any commits that won't result in changes
- ???
- Profit!
`disableDOMTestUtils` and the FB build `ReactTestUtilsFB` allowed us to
finish migrating internal callsites off of ReactTestUtils. Now that
usage is cleaned up, we can remove the flag, build artifact, and test
coverage for the deprecated utility methods.
In order to integrate the `react-reconciler` build created in #28880
with third party libraries, we need to have matching
`react-reconciler/constants` to go with it.
Bundle config: inline internal hook wrapper
Instead of reading this wrapper from 2 files for "start" and "end" and
then string modifying the templates, just inline them like the other
wrappers in this file.
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
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.
Meta uses various tools built on top of the "react-reconciler" package
but that package needs to match the version of the "react" package.
This means that it should be synced at the same time. However, more than
that the feature flags between the "react" package and the
"react-reconciler" package needs to line up. Since FB has custom feature
flags, it can't use the OSS version of react-reconciler.
In #26446 we started publishing non-minified versions of our production
build artifacts, along with source maps, for easier debugging of React
when running in production mode.
The way it's currently set up is that these builds are generated
*before* Closure compiler has run. Which means it's missing many of the
optimizations that are in the final build, like dead code elimination.
This PR changes the build process to run Closure on the non-minified
production builds, too, by moving the sourcemap generation to later in
the pipeline.
The non-minified builds will still preserve the original symbol names,
and we'll use Prettier to add back whitespace. This is the exact same
approach we've been using for years to generate production builds for
Meta.
The idea is that the only difference between the minified and non-
minified builds is whitespace and symbol mangling. The semantic
structure of the program should be identical.
To implement this, I disabled symbol mangling when running Closure
compiler. Then, in a later step, the symbols are mangled by Terser. This
is when the source maps are generated.
In React 19 React will finally stop publishing UMD builds. This is
motivated primarily by the lack of use of UMD format and the added
complexity of maintaining build infra for these releases. Additionally
with ESM becoming more prevalent in browsers and services like esm.sh
which can host React as an ESM module there are other options for doing
script tag based react loading.
This PR removes all the UMD build configs and forks.
There are some fixtures that still have references to UMD builds however
many of them already do not work (for instance they are using legacy
features like ReactDOM.render) and rather than block the removal on
these fixtures being brought up to date we'll just move forward and fix
or removes fixtures as necessary in the future.