This is all behind the `enableOwnerStacks` flag.
This is a follow up to #29088. In that I moved type validation into the
renderer since that's the one that knows what types are allowed.
However, I only removed it from `React.createElement` and not the JSX
which was an oversight.
However, I also noticed that for invalid types we don't have the right
stack trace for throws because we're not yet inside the JSX element that
itself is invalid. We should use its stack for the stack trace. That's
the reason it's enough to just use the throw now because we can get a
good stack trace from the owner stack. This is fixed by creating a fake
Throw Fiber that gets assigned the right stack.
Additionally, I noticed that for certain invalid types like the most
common one `undefined` we error in Flight so a missing import in RSC
leads to a generic error. Instead of erroring on the Flight side we
should just let anything that's not a Server Component through to the
client and then let the Client renderer determine whether it's a valid
type or not. Since we now have owner stacks through the server too, this
will still be able to provide a good stack trace on the client that
points to the server in that case.
<img width="571" alt="Screenshot 2024-06-25 at 6 46 35 PM"
src="https://github.com/facebook/react/assets/63648/6812c24f-e274-4e09-b4de-21deda9ea1d4">
To get the best stack you have to expand the little icon and the regular
stack is noisy [due to this Chrome
bug](https://issues.chromium.org/issues/345248263) which makes it a
little harder to find but once that's fixed it might be easier.
Basically make `console.error` and `console.warn` behave like normal -
when a component stack isn't appended. I need this because I need to be
able to print rich logs with the component stack option and to be able
to disable instrumentation completely in `console.createTask`
environments that don't need it.
Currently we can't print logs with richer objects because they're
toString:ed first. In practice, pretty much all arguments we log are
already toString:ed so it's not necessary anyway. Some might be like a
number. So it would only be a problem if some environment can't handle
proper consoles but then it's up to that environment to toString it
before logging.
The `Warning: ` prefix is historic and is both noisy and confusing. It's
mostly unnecessary since the UI surrounding `console.error` and
`console.warn` tend to have visual treatment around it anyway. However,
it's actively misleading when `console.error` gets prefixed with a
Warning that we consider an error level. There's an argument to be made
that some of our `console.error` don't make the bar for an error but
then the argument is to downgrade each of those to `console.warn` - not
to brand all our actual error logging with `Warning: `.
Apparently something needs to change in React Native before landing this
because it depends on the prefix somehow which probably doesn't make
sense already.
Remove module pattern function component support (flag only)
> This is a redo of #27742, but only including the flag removal,
excluding further simplifications.
The module pattern
```
function MyComponent() {
return {
render() {
return this.state.foo
}
}
}
```
has been deprecated for approximately 5 years now. This PR removes
support for this pattern.
This breaks internal tests, so must be something in the refactor. Since
it's the top commit let's revert and split into two PRs, one that
removes the flag and one that does the refactor, so we can find the bug.
The module pattern
```
function MyComponent() {
return {
render() {
return this.state.foo
}
}
}
```
has been deprecated for approximately 5 years now. This PR removes
support for this pattern. It also simplifies a number of code paths in
particular related to the concept of `IndeterminateComponent` types.
Instead of createElement.
We should have done this when we initially released jsx-runtime but
better late than never. The general principle is that our tests should
be written using the most up-to-date idioms that we recommend for users,
except when explicitly testing an edge case or legacy behavior, like for
backwards compatibility.
Most of the diff is related to tweaking test output and isn't very
interesting.
I did have to workaround an issue related to component stacks. The
component stack logic depends on shared state that lives in the React
module. The problem is that most of our tests reset the React module
state and re-require a fresh instance of React, React DOM, etc. However,
the JSX runtime is not re-required because it's injected by the compiler
as a static import. This means its copy of the shared state is no longer
the same as the one used by React, causing any warning logged by the JSX
runtime to not include a component stack. (This same issue also breaks
string refs, but since we're removing those soon I'm not so concerned
about that.) The solution I went with for now is to mock the JSX runtime
with a proxy that re-requires the module on every function invocation. I
don't love this but it will have to do for now. What we should really do
is migrate our tests away from manually resetting the module state and
use import syntax instead.
## Overview
Branched off https://github.com/facebook/react/pull/28130
## ~Failing~ Fixed by @eps1lon
The tests are currently failing because of two tests covering special
characters. I've tried a few ways to fix, but I'm stuck and will need
some help understanding why they fail and how to fix.
---------
Co-authored-by: Sebastian Silbermann <sebastian.silbermann@klarna.com>
## Summary
- yarn.lock diff +-6249, **small pr**
- use jest-environment-jsdom by default
- uncaught error from jsdom is an error object instead of strings
- abortSignal.reason is read-only in jsdom and node,
https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/reason
## How did you test this change?
ci green
---------
Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>
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.
* 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
* [Fizz] Improve text separator byte efficiency
Previously text separators were inserted following any Text node in Fizz. This increases bytes sent when streaming and in some cases such as title elements these separators are not interpreted as comment nodes and leak into the visual aspects of a page as escaped text.
The reason simple tracking on the last pushed type doesn't work is that Segments can be filled in asynchronously later and so you cannot know in a single pass whether the preceding content was a text node or not. This commit adds a concept of TextEmbedding which provides a best effort signal to Segments on whether they are embedded within text. This allows the later resolution of that Segment to add text separators when possibly necessary but avoid them when they are surely not.
The current implementation can only "peek" head if the segment is a the Root Segment or a Suspense Boundary Segment. In these cases we know there is no trailing text embedding and we can eliminate the separator at the end of the segment if the last emitted element was Text. In normal Segments we cannot peek and thus have to assume there might be a trailing text embedding and we issue a separator defensively. This should be rare in practice as it is assumed most components that will cause segment creation will also emit some markup at the edges.
* [Fizz] Improve separator efficiency when flushing delayed segments
The method by which we get segment markup into the DOM differs depending on when the Segment resolves.
If a Segment resolves before flushing begins for it's parent it will be emitted inline with the parent markup. In these cases separators may be necessary because they are how we clue the browser into breakup up text into distinct nodes that will later match up with what will be hydrated on the client.
If a Segment resolves after flushing has happened a script will be used to patch up the DOM in the client. when this happens if there are any text nodes on the boundary of the patch they won't be "merged" and thus will continue to have distinct representation as Nodes in the DOM. Thus we can avoid doing any separators at the boundaries in these cases.
After applying these changes the only time you will get text separators as follows
* in between serial text nodes that emit at the same time - these are necessary and cannot be eliminated unless we stop relying on the browser to automatically parse the correct text nodes when processing this HTML
* after a final text node in a non-boundary segment that resolves before it's parent has flushed - these are sometimes extraneous, like when the next emitted thing is a non-Text node.
In all other cases text separators should be omitted which means the general byte efficiency of this approach should be pretty good
* Deprecate renderToNodeStream
* Use renderToPipeableStream in tests instead of renderToNodeStream
This is the equivalent API. This means that we have way less test coverage
of this API but I feel like that's fine since it has a deprecation warning
in it and we have coverage on renderToString that is mostly the same.
* Fix textarea bug
The test changes revealed a bug with textarea. It happens because we
currently always insert trailing comment nodes. We should optimize that
away. However, we also don't really support complex children so we
should toString it anyway which is what partial renderer used to do.
* Update tests that assert number of nodes
These tests are unnecessarily specific about number of nodes.
I special case these, which these tests already do, because they're good
tests to test that the optimization actually works later when we do
fix it.
* Enable prefer-const rule
Stylistically I don't like this but Closure Compiler takes advantage of
this information.
* Auto-fix lints
* Manually fix the remaining callsites
* warn if passive effects get queued outside of an act() call
While the code itself isn't much (it adds the warning to mountEffect() and updateEffect() in ReactFiberHooks), it does change a lot of our tests. We follow a bad-ish pattern here, which is doing asserts inside act() scopes, but it makes sense for *us* because we're testing intermediate states, and we're manually flush/yield what we need in these tests.
This commit has one last failing test. Working on it.
* pass lint
* pass failing test, fixes another
- a test was failing in ReactDOMServerIntegrationHooks while testing an effect; the behaviour of yields was different from browser and server when wrapped with act(). further, because of how we initialized modules, act() around renders wasn't working corrrectly. solved by passing in ReactTestUtils in initModules, and checking on the finally yielded values in the specific test.
- in ReactUpdates, while testing an infinite recursion detection, the test needed to be wrapped in an act(), which would have caused the recusrsion error to throw. solived by rethrowing the error from inside the act().
* pass ReactDOMServerSuspense
* stray todo
* a better message, consistent with the state update one.
* Bump deps to Jest 22
* Prevent jsdom from logging intentionally thrown errors
This relies on our existing special field that we use to mute errors.
Perhaps, it would be better to instead rely on preventDefault() directly.
I outlined a possible strategy here: https://github.com/facebook/react/issues/11098#issuecomment-355032539
* Update snapshots
* Mock out a method called by ReactART that now throws
* Calling .click() no longer works, dispatch event instead
* Fix incorrect SVG element creation in test
* Render SVG elements inside <svg> to avoid extra warnings
* Fix range input test to use numeric value
* Fix creating SVG element in test
* Replace brittle test that relied on jsdom behavior
The test passed in jsdom due to its implementation details.
The original intention was to test the mutation method, but it was removed a while ago.
Following @nhunzaker's suggestion, I moved the tests to ReactDOMInput and adjusted them to not rely on implementation details.
* Add a workaround for the expected extra client-side warning
This is a bit ugly but it's just two places. I think we can live with this.
* Only warn once for mismatches caused by bad attribute casing
We used to warn both about bad casing and about a mismatch.
The mismatch warning was a bit confusing. We didn't know we warned twice because jsdom didn't faithfully emulate SVG.
This changes the behavior to only leave the warning about bad casing if that's what caused the mismatch.
It also adjusts the test to have an expectation that matches the real world behavior.
* Add an expected warning per comment in the same test
* Extract Jest config into a separate file
* Refactor Jest scripts directory structure
Introduces a more consistent naming scheme.
* Add yarn test-bundles and yarn test-prod-bundles
Only files ending with -test.public.js are opted in (so far we don't have any).
* Fix error decoding for production bundles
GCC seems to remove `new` from `new Error()` which broke our proxy.
* Build production version of react-noop-renderer
This lets us test more bundles.
* Switch to blacklist (exclude .private.js tests)
* Rename tests that are currently broken against bundles to *-test.internal.js
Some of these are using private APIs. Some have other issues.
* Add bundle tests to CI
* Split private and public ReactJSXElementValidator tests
* Remove internal deps from ReactServerRendering-test and make it public
* Only run tests directly in __tests__
This lets us share code between test files by placing them in __tests__/utils.
* Remove ExecutionEnvironment dependency from DOMServerIntegrationTest
It's not necessary since Stack.
* Split up ReactDOMServerIntegration into test suite and utilities
This enables us to further split it down. Good both for parallelization and extracting public parts.
* Split Fragment tests from other DOMServerIntegration tests
This enables them to opt other DOMServerIntegration tests into bundle testing.
* Split ReactDOMServerIntegration into different test files
It was way too slow to run all these in sequence.
* Don't reset the cache twice in DOMServerIntegration tests
We used to do this to simulate testing separate bundles.
But now we actually *do* test bundles. So there is no need for this, as it makes tests slower.
* Rename test-bundles* commands to test-build*
Also add test-prod-build as alias for test-build-prod because I keep messing them up.
* Use regenerator polyfill for react-noop
This fixes other issues and finally lets us run ReactNoop tests against a prod bundle.
* Run most Incremental tests against bundles
Now that GCC generator issue is fixed, we can do this.
I split ErrorLogging test separately because it does mocking. Other error handling tests don't need it.
* Update sizes
* Fix ReactMount test
* Enable ReactDOMComponent test
* Fix a warning issue uncovered by flat bundle testing
With flat bundles, we couldn't produce a good warning for <div onclick={}> on SSR
because it doesn't use the event system. However the issue was not visible in normal
Jest runs because the event plugins have been injected by the time the test ran.
To solve this, I am explicitly passing whether event system is available as an argument
to the hook. This makes the behavior consistent between source and bundle tests. Then
I change the tests to document the actual logic and _attempt_ to show a nice message
(e.g. we know for sure `onclick` is a bad event but we don't know the right name for it
on the server so we just say a generic message about camelCase naming convention).