[rcr] Update default runtimeModule to react-compiler-runtime (#31144)

Updates the compiler to always import from `react-compiler-runtime` by
default. The runtime then decides whether to use the official or
userspace implementation of useMemoCache.
This commit is contained in:
lauren
2024-10-07 17:59:33 -04:00
committed by GitHub
parent 8dd4cda380
commit 3fd3364107
8 changed files with 124 additions and 14 deletions

View File

@@ -13,7 +13,7 @@ module.exports = function (api) {
[
'babel-plugin-react-compiler',
{
runtimeModule: 'react-compiler-runtime',
target: '18',
},
],
],

View File

@@ -8,6 +8,7 @@
"dist"
],
"scripts": {
"postinstall": "./scripts/link-react-compiler-runtime.sh",
"build": "rimraf dist && rollup --config --bundleConfigAsCjs",
"test": "yarn snap:ci",
"jest": "yarn build && ts-node node_modules/.bin/jest",

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
set -eo pipefail
yarn --silent workspace react-compiler-runtime link
yarn --silent workspace babel-plugin-react-compiler link react-compiler-runtime

View File

@@ -298,7 +298,6 @@ export function compileProgram(
return;
}
const useMemoCacheIdentifier = program.scope.generateUidIdentifier('c');
const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime';
/*
* Record lint errors and critical errors as depending on Forget's config,
@@ -605,7 +604,7 @@ export function compileProgram(
if (needsMemoCacheFunctionImport) {
updateMemoCacheFunctionImport(
program,
moduleName,
getReactCompilerRuntimeModule(pass.opts),
useMemoCacheIdentifier.name,
);
}
@@ -638,8 +637,12 @@ function shouldSkipCompilation(
}
}
const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime';
if (hasMemoCacheFunctionImport(program, moduleName)) {
if (
hasMemoCacheFunctionImport(
program,
getReactCompilerRuntimeModule(pass.opts),
)
) {
return true;
}
return false;
@@ -1126,3 +1129,31 @@ function checkFunctionReferencedBeforeDeclarationAtTopLevel(
return errors.details.length > 0 ? errors : null;
}
type ReactCompilerRuntimeModule =
| 'react/compiler-runtime' // from react namespace
| 'react-compiler-runtime'; // npm package
function getReactCompilerRuntimeModule(
opts: PluginOptions,
): ReactCompilerRuntimeModule {
let moduleName: ReactCompilerRuntimeModule | null = null;
switch (opts.target) {
case '17':
case '18': {
moduleName = 'react-compiler-runtime';
break;
}
case '19': {
moduleName = 'react/compiler-runtime';
break;
}
default:
CompilerError.invariant(moduleName != null, {
reason: 'Expected target to already be validated',
description: null,
loc: null,
suggestions: null,
});
}
return moduleName;
}

View File

@@ -0,0 +1,45 @@
## Input
```javascript
// @target="18"
function Component() {
return <div>Hello world</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [],
isComponent: true,
};
```
## Code
```javascript
import { c as _c } from "react-compiler-runtime"; // @target="18"
function Component() {
const $ = _c(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <div>Hello world</div>;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [],
isComponent: true,
};
```
### Eval output
(kind: ok) <div>Hello world</div>

View File

@@ -0,0 +1,11 @@
// @target="18"
function Component() {
return <div>Hello world</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [],
isComponent: true,
};

View File

@@ -2,7 +2,9 @@
## Input
```javascript
// @runtimeModule="react-forget-runtime"
// @runtimeModule="react-compiler-runtime"
import {useState} from 'react';
function Component(props) {
const [x, setX] = useState(1);
let y;
@@ -10,10 +12,12 @@ function Component(props) {
y = x * 2;
}
return (
<Button
<button
onClick={() => {
setX(10 * y);
}}></Button>
}}>
Click me
</button>
);
}
@@ -28,7 +32,9 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react-forget-runtime"; // @runtimeModule="react-forget-runtime"
import { c as _c } from "react/compiler-runtime"; // @runtimeModule="react-compiler-runtime"
import { useState } from "react";
function Component(props) {
const $ = _c(5);
const [x, setX] = useState(1);
@@ -48,11 +54,13 @@ function Component(props) {
let t1;
if ($[3] !== t0) {
t1 = (
<Button
<button
onClick={() => {
setX(10 * y);
}}
/>
>
Click me
</button>
);
$[3] = t0;
$[4] = t1;

View File

@@ -1,4 +1,6 @@
// @runtimeModule="react-forget-runtime"
// @runtimeModule="react-compiler-runtime"
import {useState} from 'react';
function Component(props) {
const [x, setX] = useState(1);
let y;
@@ -6,10 +8,12 @@ function Component(props) {
y = x * 2;
}
return (
<Button
<button
onClick={() => {
setX(10 * y);
}}></Button>
}}>
Click me
</button>
);
}