react changelog



Welcome to the latest updates! Here's a rundown of the coolest changes and fixes we've made recently. 🎉

New Features

  • Optimize Instruction Reordering: We've turbocharged the compiler with a new instruction reordering strategy! Now, LoadLocal instructions can be reordered more efficiently, and statement blocks have a more optimal reordering process. This helps merge scopes better and reduces memo slots in fixtures.

  • New Flags GitHub Action: We've added a new GitHub action for checking yarn flags. This mirrors the existing CircleCI workflow to ensure everything runs smoothly on both platforms.

  • New Fizz GitHub Action: Introduced a GitHub action for checking the inlined Fizz runtime. This action ensures that the Fizz runtime is always up to date by mirroring the CircleCI workflow.

  • New Package: react-html: Say hello to react-html! This new package includes a renderToMarkup export for rendering HTML that isn't meant to be hydrated. Perfect for emails, RSS feeds, and more.

  • New Lint GitHub Action: We've added a new linting action to GitHub. This action runs prettier, eslint, and other checks to keep our codebase in tip-top shape.

Bugfixes

  • Validate Against Locals Being Reassigned After Render: Added a validation pass to ensure local variables aren't reassigned by functions called after rendering. This prevents inconsistencies in subsequent renders.

  • Warn for Invalid Type in Renderer: Improved error handling for invalid types in the renderer, ensuring the correct stack trace is shown. This is all behind the enableOwnerStacks flag.

  • Examples of Invalid Code Reassigning Locals Outside of Render: Added test fixtures to handle cases where local variables are wrongly reassigned outside of the render function.

  • Repro for Nested Function Local Reassignment Issue: Introduced a repro case demonstrating issues with nested function local reassignments. This helps pinpoint and address the problem.

  • New Error Message for Awaiting the Client Export: Updated the error message for attempting to await client exports, making it clearer and more helpful for avoiding incorrect usage.

Chores

  • Remove CircleCI Yarn Flags Job: We've removed the CircleCI yarn_flags job now that it's been migrated to GitHub actions. This helps streamline our CI/CD process.

That's all for now! Keep coding, keep smiling, and stay awesome! 🚀✨

Included Commits

2024-06-21T15:41:27 See commit

This commit adds a new lint GitHub action by copying the existing circleci workflow for linting into GitHub actions. The circleci workflow has not been removed at this point to ensure parity. The new lint GitHub action includes steps for running prettier, eslint, checking licenses, and testing print warnings on the main branch.

The additions in the commit include a new lint.yml file in the .github/workflows directory with a total of 79 changes. The lint GitHub action is triggered on push events to the main branch and pull requests. It runs various linting tasks such as prettier, eslint, license checking, and testing print warnings on the ubuntu-latest environment using yarn for dependency management. Overall, this commit aims to streamline the linting process by transitioning from circleci to GitHub actions.

Files changed

  • .github/workflows/lint.yml
2024-06-21T18:57:58 See commit

This commit removes the circleci yarn_flags job from the .circleci/config.yml file as it has been migrated to GitHub actions. The changes include deleting the yarn_flags job and updating the build_and_test workflow to remove references to the yarn_flags job. The commit also resolves a pull request related to this change.

Overall, this commit streamlines the CI/CD process by removing redundant configuration in CircleCI and transitioning the yarn_flags job to GitHub actions. This simplification of the CI/CD setup helps improve the efficiency and maintenance of the project's build and test workflows.

Files changed

  • .circleci/config.yml
2024-06-21T18:57:58 See commit

This commit adds new flags to the GitHub action by copying the existing circleci workflow for yarn flags. The circleci job has not been removed at this time in order to ensure parity. The changes include adding a new workflow file called flags.yml, which specifies the steps for checking flags on push and pull requests. The job runs on ubuntu-latest and includes steps for checking out the code, setting up Node, restoring cached node_modules, installing dependencies with yarn, and running the yarn flags command.

Overall, this commit introduces a new GitHub action for checking flags in the React repository. The workflow is set up to run on push events to the main branch and pull requests, with specific paths ignored. The steps in the job involve setting up Node, restoring cached dependencies, and running the yarn flags command to check for any flags in the codebase. This addition ensures that the project maintains consistency between the existing circleci workflow and the new GitHub actions.

Files changed

  • .github/workflows/flags.yml
2024-06-21T23:48:00 See commit

This commit optimizes instruction reordering in the compiler. The PR includes two main changes: first, it allows LoadLocal instructions to be reordered under specific conditions, and second, it introduces a more optimal reordering strategy for statement blocks while maintaining the existing approach for expression blocks. The goal is to maximize the ability to merge scopes by reordering instructions closer to their dependencies.

To achieve this, the commit uses different strategies for value blocks and regular blocks. For value blocks, the final instruction representing the block's value is emitted explicitly to preserve order, while for regular blocks, terminal operands are emitted first followed by reorderable instructions. This approach aims to improve the effectiveness of optimization by moving instructions closer to their dependencies for better scope merging. The commit also updates code sharing between value blocks and regular blocks, addressing the inadvertent reduction in optimization effectiveness from a previous attempt.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/Optimization/InstructionReordering.ts
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-consecutive-scopes-reordering.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/merge-scopes-callback.expect.md
2024-06-21T23:48:00 See commit

This commit adds a fixture for optimization across scopes in the compiler. The fixture is based on an internal case where the current output is more verbose than the original memoization. The comment in the fixture explains the heuristic that can be applied for optimization. The commit includes changes to the fixture file for reordering across blocks, adding code and an evaluation output. The original memoization is described as having one output and one dependency, but the current approach only considers consecutive scopes for merging, leading to suboptimal results. The goal is to build a dependency graph of scopes to identify transitive dependencies and optimize the output.

The code changes in the commit involve transforming the original memoization logic into a more optimized version using internal functions and variables. The code now includes conditional checks and assignments to handle changes in the 'config' object and functions 'a' and 'b'. The final output is a component that utilizes the useMemo hook to create an object with 'a' and 'b' functions based on the 'config' dependency. The commit aims to improve the optimization of scopes in the compiler by considering the data flow and dependencies more effectively.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reordering-across-blocks.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reordering-across-blocks.js
2024-06-22T16:33:38 See commit

This commit adds a new GitHub action for checking the inlined Fizz runtime, copying the existing circleci workflow for this task. The circleci job has not been removed at this point to ensure parity between the two systems. The new GitHub action is configured to run on pushes to the main branch and pull requests, with specific paths ignored. It includes steps to check the generated inline Fizz runtime and ensure it is up to date by restoring cached node modules, installing dependencies, generating the runtime, and checking for any changes.

The changes made in this commit include adding a new GitHub workflow file for Fizz, with 30 additions and no deletions. The workflow is set up to run on specific triggers and includes a job to confirm the generated inline Fizz runtime is up to date. The steps in the job involve checking out the code, setting up the node environment, restoring cached node modules, installing dependencies, generating the Fizz runtime, and checking for any changes before completing the workflow.

Files changed

  • .github/workflows/fizz.yml
2024-06-26T17:47:39 See commit

This commit adds a new error message for awaiting the client export in React, specifically changing the error message that appears when trying to access the .then property on the server. The previous message, "Cannot access .then on server," was not clear when attempting to await or do promise chains on client references. The new error message provides more information about the usage and clarifies that you cannot await a client module from a server component, helping users avoid incorrect usage.

The changes include modifying the error message in the ReactFlightTurbopackReferences and ReactFlightWebpackReferences files to throw an error when trying to access the .then property on a client module. Additionally, unit tests were added to ensure that the error is thrown correctly when awaiting a client module prop of client exports, providing validation for the new error message implementation.

Files changed

  • packages/react-server-dom-turbopack/src/ReactFlightTurbopackReferences.js
  • packages/react-server-dom-webpack/src/ReactFlightWebpackReferences.js
  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
2024-06-26T22:09:06 See commit

This commit introduces changes to handle examples of invalid code that reassign locals outside of the render function in React. The commit includes modifications to test fixtures for scenarios where local variables are reassigned in effect hooks, hook arguments, and JSX callback functions. The changes aim to prevent issues that arise when reassigning locals from functions that escape, ensuring that the correct version of the local variable is updated and observed in the if conditions.

Additionally, the commit includes modifications to the SproutTodoFilter in the snap package, adding entries to the skipFilter set for specific scenarios that should error, including cases related to reassigning local variables in JSX callback functions, hook arguments, and effect hooks. These changes are designed to improve error handling and prevent issues related to invalid reassignments of local variables in React code.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-reassign-local-variable-in-effect.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-reassign-local-variable-in-effect.js
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-reassign-local-variable-in-hook-argument.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-reassign-local-variable-in-hook-argument.js
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-reassign-local-variable-in-jsx-callback.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-reassign-local-variable-in-jsx-callback.js
  • compiler/packages/snap/src/SproutTodoFilter.ts
2024-06-26T23:02:09 See commit

This commit adds a validation pass to ensure that local variables are not reassigned by functions called after rendering in React components. The validation process involves building a mapping of context variables in the outer component or hook, identifying functions that may reassign those variables, propagating aliases of those functions, and disallowing passing those functions with a Freeze effect. The goal is to prevent inconsistencies in subsequent renders caused by reassigning variables after rendering is completed.

The commit includes changes to add the validation pass in the compiler pipeline, as well as new error fixtures to demonstrate cases where reassigning locals after render is detected and flagged as an error. Additionally, a new file is added to implement the validation logic for checking reassignments of local variables in React components and hooks.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts
  • compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateLocalsNotReassignedAfterRender.ts
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-in-hook-return-value.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-in-hook-return-value.js
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-variable-in-effect.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-variable-in-hook-argument.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-variable-in-jsx-callback.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutable-range-shared-inner-outer-function.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutable-range-shared-inner-outer-function.js
2024-06-27T00:07:38 See commit

This commit includes a repro case for a nested function local reassignment issue in the compiler. The provided code demonstrates a scenario where reassigning a local variable within a nested function causes unexpected behavior when React Compiler is enabled. The issue arises from the fact that the reassignment function is created only once with React Compiler, leading to the wrong version of the local variable being reassigned, resulting in an error being thrown.

In addition to the repro case, some modifications were made to the SproutTodoFilter in the Snap package, adding the "todo.invalid-nested-function-reassign-local-variable-in-effect" as a skipped filter. This change ensures that the mentioned issue is excluded from certain executions within the module, addressing the specific problem related to nested function local reassignment in the compiler.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-nested-function-reassign-local-variable-in-effect.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.invalid-nested-function-reassign-local-variable-in-effect.js
  • compiler/packages/snap/src/SproutTodoFilter.ts
2024-06-27T16:09:40 See commit

This commit adds a new package called react-html with a renderToMarkup export, which is intended for rendering HTML that is not meant to be hydrated. This package can be used as a standalone package separate from react-dom, and is primarily designed to support a subset of HTML that can be used for embedding in things like emails, RSS/Atom feeds, or other distributions. It is considered a successor to renderToStaticMarkup and does not support "Client Components", useEffect, useState, or other client-side features, as it will never be hydrated.

The implementation of this new package currently only supports Server Components, with a potential plan to add support for Client Components in the future. The build dimension used in this implementation wires up a build that encapsulates a Flight Server -> Flight Client -> Fizz stream to render Server Components for server-side rendering. There are some challenges with using Flight in a Server Component environment, as it depends on the client version of "react", which is addressed by embedding the client version of "react" shared internals into the build. Additionally, there are some issues with TextEncoder/TextDecoder and handling large strings that need to be resolved before shipping.

Files changed

  • packages/react-client/src/forks/ReactFlightClientConfig.dom-bun.js
  • packages/react-client/src/forks/ReactFlightClientConfig.dom-legacy.js
  • packages/react-html/README.md
  • packages/react-html/index.js
  • packages/react-html/npm/index.js
  • packages/react-html/npm/react-html.react-server.js
  • packages/react-html/package.json
  • packages/react-html/react-html.react-server.js
  • packages/react-html/src/ReactHTMLLegacyClientStreamConfig.js
  • packages/react-html/src/ReactHTMLServer.js
  • packages/react-html/src/__tests__/ReactHTMLServer-test.js
  • packages/react-server/src/forks/ReactFlightServerConfig.dom-legacy.js
  • scripts/error-codes/codes.json
  • scripts/rollup/bundles.js
  • scripts/rollup/forks.js
  • scripts/shared/inlinedHostConfigs.js
2024-06-27T16:10:09 See commit

This commit addresses an issue with invalid types in the renderer by implementing a warning system behind the enableOwnerStacks flag. The type validation was moved into the renderer in a previous commit, but it was only removed from React.createElement and not from JSX, leading to oversight. The commit also improves the stack trace for throws related to invalid types by creating a fake Throw Fiber with the correct stack, allowing for better error handling.

Furthermore, the commit addresses errors related to certain invalid types like undefined in Flight, where a missing import in RSC could lead to a generic error. Instead of erroring on the Flight side, the approach now is to let the client renderer determine whether a type is valid or not, providing a good stack trace that points to the server. Various files were modified to implement these changes and improve error handling in the renderer.

Files changed

  • packages/react-client/src/__tests__/ReactFlight-test.js
  • packages/react-dom/src/__tests__/ReactComponent-test.js
  • packages/react-dom/src/__tests__/ReactDOMServerIntegrationElements-test.js
  • packages/react-dom/src/__tests__/ReactLegacyErrorBoundaries-test.internal.js
  • packages/react-reconciler/src/ReactChildFiber.js
  • packages/react-reconciler/src/ReactFiber.js
  • packages/react-reconciler/src/__tests__/ErrorBoundaryReconciliation-test.internal.js
  • packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
  • packages/react-server/src/ReactFlightServer.js
  • packages/react/src/__tests__/ReactElementValidator-test.internal.js
  • packages/react/src/__tests__/ReactJSXElementValidator-test.js
  • packages/react/src/jsx/ReactJSXElement.js