Commit Graph
19463 Commits
Author SHA1 Message Date
Lauren Tan 6d6518161a Cleanup packages directory
Prepare to move to a yarn workspaces setup
2023-06-02 13:06:36 -04:00
Lauren Tan 479ef4045b Move entrypoint into its own directory 2023-06-02 13:06:35 -04:00
Lauren Tan 2eded946f8 Make CompilerEntrypoint a little more generic
These are still quite Babel specific, but the interface is slightly more 
generic: CompilerEntrypoint takes a non-Babel specific CompilerPass as an 
argument instead of passing Babel's PluginPass directly. 

In the future we can consider lowering the whole Program into HIR but that 
involves a significant lift in our representation and a small amount of new 
syntax to support (eg import statements), so this PR is the extent of this stack 
for now
2023-06-02 13:06:35 -04:00
Lauren Tan b98ee34f45 Delegate BabelPlugin to CompilerEntrypoint
Moves the existing logic in BabelPlugin to its own files
2023-06-02 13:06:34 -04:00
Lauren Tan 9077ac1f27 Copy files from src/Babel to src/ 2023-06-02 13:06:34 -04:00
Josh Story e1ad4aa361 [Fizz][Float] stop automatically preloading scripts that are not script resources (#26877)
Currently we preload all scripts that are not hoisted. One of the
original reasons for this is we stopped SSR rendering async scripts that
had an onLoad/onError because we needed to be able to distinguish
between Float scripts and non-Float scripts during hydration. Hydration
has been refactored a bit and we can not get around this limitation so
we can just emit the async script in place. However, sync and defer
scripts are also preloaded. While this is sometimes desirable it is not
universally so and there are issues with conveying priority properly
(see fetchpriority) so with this change we remove the automatic
preloading of non-Float scripts altogether.

For this change to make sense we also need to emit async scripts with
loading handlers during SSR. we previously only preloaded them during
SSR because it was necessary to keep async scripts as unambiguously
resources when hydrating. One ancillary benefit was that load handlers
would always fire b/c there was no chance the script would run before
hydration. With this change we go back to having the ability to have
load handlers fired before hydration. This is already a problem with
images and we don't have a generalized solution for it however our
likely approach to this sort of thing where you need to wait for a
script to load is to use something akin to `importScripts()` rather than
rendering a script with onLoad.
2023-06-01 13:34:36 -07:00
Josh Story 5fb2c15a89 [Fizz][Float] stop preloading stylesheets that are not stylesheet resources (#26873)
We previously preloaded stylesheets that were rendered in Fizz. The idea
was we'd get a headstart fetching these resources since we know they are
going to be rendered. However to really be effective non-float
stylesheets need to rendered in the head and the preload here is not
helpful and potentially hurtful to perf in a minor way. This change
removes this functionality to make the code smaller and simpler
2023-06-01 13:23:53 -07:00
Josh Story 042d8f606c [Float] support fetchpriority on ReactDOM.preload() and ReactDOM.preinit() (#26880)
exposes fetchPriority as an option for `ReactDOM.preload()` and
`ReactDOM.preinit()`

the typings should be `'high' | 'low' | 'auto'`
2023-06-01 13:10:55 -07:00
Tianyu Yao 811022232e Always trigger componentWillUnmount in StrictMode (#26842)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
In StrictMode, React currently only triggers `componentWillUnmount` if
`componentDidMount` is defined. This would miss detecting issues like
initializing resources in constructor or componentWillMount, for
example:
```
class Component {
  constructor() {
     this._subscriptions = new Subscriptions();
  }
  componentWillUnmount() {
     this._subscriptions.reset();
  } 
}
``` 

The PR makes `componentWillUnmount` always run in StrictMode.


## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->
`yarn test ci`
2023-06-01 10:34:31 -07:00
Ricky 018c58c9c6 Clean up enableSyncDefaultUpdates flag a bit (#26858)
## Overview

Does a few things:
- Renames `enableSyncDefaultUpdates` to
`forceConcurrentByDefaultForTesting`
- Changes the way it's used so it's dead-code eliminated separate from
`allowConcurrentByDefault`
- Deletes a bunch of the gated code

The gates that are deleted are unnecessary now. We were keeping them
when we originally thought we would come back to being concurrent by
default. But we've shifted and now sync-by default is the desired
behavior long term, so there's no need to keep all these forked tests
around.

I'll follow up to delete more of the forked behavior if possible.
Ideally we wouldn't need this flag even if we're still using
`allowConcurrentByDefault`.
2023-06-01 09:24:56 -04:00
Josh Story ae31d2ea3c [Fizz] preload bootstrapModules (#26754)
stacked on #26753 

Adds support for preloading bootstrapModules. We don't yet support
modules in Float's public interface but this implementation should be
compatible with what we do when we add it.
2023-05-31 16:48:27 -07:00
Josh Story b864ad4397 [Fizz] preload bootstrapScripts (#26753)
This PR adds a preload for bootstrapScripts. preloads are captured
synchronously when you create a new Request and as such the normal logic
to check if a preload already exists is skipped.
2023-05-31 16:25:35 -07:00
Joe Savona 7fddf42d06 [ez] Hooks dont escape, their args do 2023-05-31 16:05:07 -07:00
Joe Savona 0ae37f1568 Treat setState as non-reactive
Updates PruneNonReactiveDependencies to treat setState functions as 
non-reactive, since we know they have a stable identity. This is based on type 
inference and our recently added definitions for useState and its return type, 
so it's conservative and will only work when our inference can prove that the 
scope dependency has the SetState type. 

Note that this approach is simple and has limitations, notably the fact that the 
setState is non-reactive doesn't propagate. But it's simple, trivially correct, 
and already improves codegen somewhat, so i figured it's worth landing for now. 

## Test Plan 

Tested on internal app
2023-05-31 14:29:31 -07:00
Joe Savona 9c453ad26f Validate frozen lambdas are actually frozen
Adds validation to reject freezing mutable lambdas, since lambdas cannot _be_ 
frozen, they're either frozen or not. Example invalid code: 

```javascript 

function Component(props) { 

const x = {value: ""}; 

const onChange = (e) => { 

// MUTATION!!!!! 

x.value = e.target.value; 

setX(x); 

}; 

return <input value={x.value} onChange={onChange} />; 

} 

``` 

Note that there is a separate issue in which we are not detecting lambdas that 
would definitely modify immutable values. We may need to distinguish 
ConditionallyCapture (captures if the value is mutable, otherwise readonly) from 
Capture (definitely mutates) in order to make that case work. But already this 
validation helps prevent some invalid code.
2023-05-31 14:03:02 -07:00
Joe Savona 8e341294d0 [be] Upgrade to TypeScript 5.1
The functional changes in 5.1 don't seem that compelling but there are some perf 
improvements, supposedly.
2023-06-01 13:23:09 -07:00
Josh Story e1e68b9f7f [Fiber][Float] preinitialized stylesheets should support integrity option (#26881)
preinitialized stylesheets did not render the integrity option on the
client implementation of Float. This was an oversight.
2023-05-31 13:48:19 -07:00
Joe Savona a5a86c302a Validate against ref access in render 2023-05-31 09:38:28 -07:00
Joe Savona af94b075c0 Option to disable memoization
Adds a `removeAllMemoization` flag that runs the entire compiler pipeline but 
strips out all memoization. The intent is to be able to compare (in limited 
use-cases) the performance of an existing app with all memoization removed, vs 
the performance with manual memoization, vs the performance with Forget enabled. 

In terms of how this works: we already strip out useMemo/useCallback since 
Forget is more accurate. The new option adds an extra pass that strips out all 
reactive scopes. Collectively this leaves ~zero memoization within components 
(this does leave React.memo, but close enough).
2023-05-31 08:03:36 -07:00
Sathya Gunasekaran 793b69243f [hir] Track context refs when inferring reactive ids 2023-05-31 15:37:39 +01:00
Sathya Gunasekaran b447c93edc [test] Add failing test for lambda turning value reactive 2023-05-31 15:37:35 +01:00
Sathya Gunasekaran 2c8f6888e6 [hir] Failing test for adding ref as dep incorrectly 2023-05-31 13:55:00 +01:00
Sathya Gunasekaran 91f41f5ee3 [hir] Don't track ref value as a valid dep 2023-05-31 13:54:59 +01:00
Sathya Gunasekaran bedf0cc6c5 [hir] Don't track ref.current as a valid dep 2023-05-31 13:54:58 +01:00
Josh Story 1cea384480 [Fiber] retain scripts on clearContainer and clearSingleton (#26871)
clearContainer and clearSingleton both assumed scripts could be safely
removed from the DOM because normally once a script has been inserted
into the DOM it is executable and removing it, even synchronously, will
not prevent it from running. However There is an edge case in a couple
browsers (Chrome at least) where during HTML streaming if a script is
opened and not yet closed the script will be inserted into the document
but not yet executed. If the script is removed from the document before
the end tag is parsed then the script will not run. This change causes
clearContainer and clearSingleton to retain script elements. This is
generally thought to be safe because if we are calling these methods we
are no longer hydrating the container or the singleton and the scripts
execution will happen regardless.
2023-05-30 13:12:56 -07:00
Sathya Gunasekaran 1d536af4f7 [hir] Refactor checkValidDependencyId to accept a dep 2023-05-30 13:44:30 +01:00
Mofei Zhang fc13557d30 [tests] remove jest fixture tests
--- 

Remove jest fixture tests in favor of snap runner. Main reasons: 

- maintaining feature flags and compatible behavior required syncing all changes 
to 3 files (`generateTestsFromFixtures`, `compiler-test`, and `compiler-worker`) 

- jest snapshot test file causes rebase conflicts on most rebases 

- speed 🙌 

$ time yarn test compiler-test 

(the extra test here is `has a consistent extension for input fixtures`) 

``` 

Test Suites: 1 passed, 1 total 

Tests:       37 skipped, 480 passed, 517 total 

Snapshots:   479 passed, 479 total 

Time:        27.668 s 

Ran all test suites matching /compiler-test/i. 

✨  Done in 43.18s. 

yarn test compiler-test  57.05s user 3.85s system 139% cpu 43.546 total 

``` 

$ time yarn snap 

``` 

478 Tests, 478 Passed, 0 Failed 

✨  Done in 13.12s. 

yarn snap  53.96s user 9.35s system 468% cpu 13.518 total 

``` 

Jest and snap should have the same set of features: 

- report test failures via exit status (used by Git Actions) 

- watch mode 

- breakpoints + `debugger` statements 

- note that `--sync` is not required for this 

- skip `todo.` prefixed fixtures 

- fixtures in nested directories e.g. `rules-of-hooks/testname.js` 

- filter mode (via editing `testfilter.txt`) 

- filter + debug mode 

(1) edit `testfilter.txt` to filter out all but one test 

(2) add `@debug` pragma to the first line of the test 

testfilter.txt 

```js 

// @only 

testfixture_basename1 

testfixture_basename2 

```
2023-05-26 13:18:38 -04:00
Mofei Zhang 71c9743e38 [snap] Fix vscode debugger attaching to forked proc
Turns out I just forgot to forward `process.env` when forking 😅 

`debugger` statements and breakpoints should work with both `--sync` and 
`--no-sync` (default) modes
2023-05-26 13:18:37 -04:00
Sebastian Markbåge a1f97589fd Compare name when hydrating hidden fields to filter out extra form action fields (#26846)
This solves an issue where if you inject a hidden field in the beginning
of the form, we might mistakenly hydrate the injected one that was part
of an action.

I'm not too happy about how specific this becomes. It's similar to Float
but in general we don't do this deep comparison.

See https://github.com/vercel/next.js/issues/50087
2023-05-26 12:54:01 -04:00
Ricky 0210f0b082 Update enableSyncDefaultUpdates for www (#26857)
If this is false, it dead code eliminates the path to use the root flag.
Will follow up to clean this up.
2023-05-25 21:33:07 -04:00
Andrew Clark 4daccade04 Remove temporary CircleCI workaround (#26855)
There was a CircleCI bug that prevented the sizebot job from accessing
the artifacts API. I had added a temporary workaround to pull from a
mirror instead. This seems to have been fixed, so I can remove the
workaround.
2023-05-25 13:38:39 -04:00
Jan Kassens 18dedde6a7 [flow] upgrade to 0.206.0 (#26850)
Small upgrade. The one impact was deprecation of `$Shape` where it seems
like we can just use a plain object with optional key.
2023-05-25 13:37:31 -04:00
Jan Kassens 9a72e62271 run SchedulerFeatureFlags with variant flags again (#26851)
With df12d7eac4 I accidentally made it so
that tests aren't run with the 2 variant modes for most
SchedulerFeatureFlags anymore. This fixes it with the same approach as
ee4233bdbc.

Test Plan:
Run and notice the boolean flags follow the variant:
```
yarn test-www --variant=true
yarn test-www --variant=false
```
2023-05-25 10:38:33 -04:00
Ricky ee4233bdbc Move enableSyncDefaultUpdates to test config (#26847) 2023-05-24 18:25:30 -04:00
Samuel Susla 6fc3333b68 Add $FlowFixMe to fix React Native DiffTrain (#26841) 2023-05-24 17:42:16 +01:00
Joe Savona 99257aa430 Enable more flags on playground 2023-05-23 16:55:10 -07:00
Joe Savona 91dcf24e67 Add test case for invalid lambdas
This is the example we discussed in our design sync. 

```javascript 

function Component(props) { 

const [x, setX] = useState({ value: "" }); 

const onChange = (e) => { 

// INVALID! should use copy-on-write and pass the new value 

x.value = e.target.value; 

setX(x); 

}; 

return <input value={x.value} onChange={onChange} />; 

} 

``` 

Here `onChange` is a mutable lambda, and it should be invalid to pass a mutable 
lambda where a frozen value is expected. This is because unlike other value 
types, you cannot freeze a lambda — the only choice is to not call it at all. 

Note that there is a harder case to catch: 

```js 

function Component(props) { 

const [x, setX] = useState({ value: "" }); 

const onChange = (e) => { 

// INVALID! should use copy-on-write and pass the new value 

x.value = e.target.value; 

setX(x); 

}; 

const x = constructAValueThatMaybeAliasesItsInput(onChange); 

return <input value={x.value} onChange={x.maybeGetTheLambdaBack()} />; 

} 

``` 

This case demonstrates how mutable lambdas can be captured and then accessed 
later — the analysis to catch this case is more sophisticated bc it involves 
inferring that `x` aliases a mutable lambda. But we also can't be sure that `x` 
does alias the lambda, so disallowing this code could prevent a lot of valid 
code from compiling. My hypothesis is that we should start with at least 
validating the example at the top, while allowing the second case for now.
2023-05-25 16:08:10 -07:00
Joe Savona edbb6e2bdb Test case for Array.push on frozen array
Just making sure that we reject this
2023-05-25 16:00:35 -07:00
Joe Savona 3381ce7ea8 Array.prototype.join
Trivial
2023-05-25 15:57:09 -07:00
Joe Savona 8be5423e3b Type Array.prototype.map/filter
We can now type `Array.prototype.{map,filter}`: 

* The callee is ConditionallyMutable because, although the array itself is not 
modified, its items flow into the lambda and may be modified there. 

* The argument is ConditionallyMutable because it accepts both mutable and 
immutable lambdas. Mutate would disallow immutable lambdas (wrong), while Read 
would be incorrect for mutable lambdas since calling them triggers mutation.
2023-05-25 14:50:14 -07:00
Joe Savona 75a1972584 More tests for effect enforcement
Adds test cases to ensure we're correctly inferring mutative builtin operations 
— property store, computed property store, property deletion, and computed 
property deletion — as definite mutation and that we're rejecting inputs where 
these operations are used on immutable/frozen values.
2023-05-25 14:33:02 -07:00
Joe Savona 9766e19805 Add Effect.Mutate for known mutation
Adds back `Effect.Mutate`, and changes so that `Effect.ConditionallyMutate` 
never rejects frozen/immutable values, while `Effect.Mutate` _always_ rejects 
frozen/immutable values.
2023-05-25 13:54:35 -07:00
Joe Savona 40cf400f72 Rename Effect.Mutate -> ConditionallyMutate
We currently use `Effect.Mutate` both for places that _may_ mutate (ie untyped 
function calls) and for places that have known mutation (typed function calls, 
or operations like `delete x.y`). We then use a separate mechanism to decide 
whether to reject the input, with some call paths checking the effect and others 
not. 

This stack refactors this logic in InferReferenceEffects per our discussion, so 
that `Effect.ConditionallyMutate` is for "may or may not mutate" either because 
we're not 100% sure (untyped function) or because the mutation depends on the 
operand (ie, a callback arg that will be invoked and thus will mutate if the 
lambda is mutable, not mutate if the lambda is immutable). Later diffs add back 
`Effect.Mutate` as "definitely 100% mutating".
2023-05-25 13:41:09 -07:00
Joe Savona 37d044763b Define types for useState/useRef
Defines 4 new types: 

* Return type of `useState()`, which has properties "0" and "1" to allow us to 
infer the types when destructuring 

* Type of useState() set state function 

* Return type of `useRef()` so we know what is a ref 

* Type of ref.current, so we know what is a ref *value* 

Example: 

<img width="1670" alt="Screenshot 2023-05-24 at 9 59 37 AM" 
src="https://github.com/facebook/react-forget/assets/6425824/3ee7d04a-fda3-4b7b-89b7-d205d9a6fd0d">
2023-05-24 09:54:10 -07:00
Joe Savona c87a1916f4 Infer property types for destructuring 2023-05-24 09:54:07 -07:00
Mofei Zhang ecc730c587 [FeatureFlag] Toggle enableTreatHooksAsFunctions default to true
--- 

Toggle default to true, since this should be a no-op refactor. 

Tests: 

- test fixtures 

- ran on Store + - and saw no difference in compiled output 

- [diff](P744101621) with 
`enableTreatHooksAsFunctions=false` 

- [diff](P744105565) with 
`enableTreatHooksAsFunctions=true`
2023-05-23 16:11:38 -04:00
Mofei Zhang 08a8891245 Test: unknown hooks should not assert effects 2023-05-23 13:55:12 -04:00
Mofei Zhang b76ee1ab32 [types] Consolidate Hook and Function types: Hooks are functions 2023-05-23 13:55:10 -04:00
Yen-Wei Liu 535c038d15 Update preload links to support nonce and fetchpriority (#26826)
Currently when React generates rel=preload link tags for script/stylesheet resources, it will not carryover nonce and fetchpriority values if specified on the original elements.

This change ensures that the preload links use the nonce and fetchPriority values if they were specified.
2023-05-22 22:56:17 -04:00
Mofei Zhang 47e9a2b8a5 [FeatureFlag] add enableTreatHooksAsFunctions 2023-05-22 19:37:53 -04:00