@samitouri / QOS-React-1 / commits / 3fd3364107

[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.

lauren committed Oct 7, 2024 at 17:59 UTC 3fd3364107ba1fa0e8edf86ee9cb9562a9be3929
8 files changed +124 -14
compiler/apps/playground/babel.config.js
+1 -1
@@ -13,7 +13,7 @@ module.exports = function (api) {
13 [
14 'babel-plugin-react-compiler',
15 {
16 - runtimeModule: 'react-compiler-runtime',
16 + target: '18',
17 },
18 ],
19 ],
compiler/packages/babel-plugin-react-compiler/package.json
+1
@@ -8,6 +8,7 @@
8 "dist"
9 ],
10 "scripts": {
11 + "postinstall": "./scripts/link-react-compiler-runtime.sh",
12 "build": "rimraf dist && rollup --config --bundleConfigAsCjs",
13 "test": "yarn snap:ci",
14 "jest": "yarn build && ts-node node_modules/.bin/jest",
compiler/packages/babel-plugin-react-compiler/scripts/link-react-compiler-runtime.sh new
+10
@@ -0,0 +1,10 @@
1 +#!/usr/bin/env bash
2 +# Copyright (c) Meta Platforms, Inc. and affiliates.
3 +#
4 +# This source code is licensed under the MIT license found in the
5 +# LICENSE file in the root directory of this source tree.
6 +
7 +set -eo pipefail
8 +
9 +yarn --silent workspace react-compiler-runtime link
10 +yarn --silent workspace babel-plugin-react-compiler link react-compiler-runtime
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts
+35 -4
@@ -298,7 +298,6 @@ export function compileProgram(
298 return;
299 }
300 const useMemoCacheIdentifier = program.scope.generateUidIdentifier('c');
301 - const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime';
301
302 /*
303 * Record lint errors and critical errors as depending on Forget's config,
@@ -605,7 +604,7 @@ export function compileProgram(
604 if (needsMemoCacheFunctionImport) {
605 updateMemoCacheFunctionImport(
606 program,
608 - moduleName,
607 + getReactCompilerRuntimeModule(pass.opts),
608 useMemoCacheIdentifier.name,
609 );
610 }
@@ -638,8 +637,12 @@ function shouldSkipCompilation(
637 }
638 }
639
641 - const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime';
642 - if (hasMemoCacheFunctionImport(program, moduleName)) {
640 + if (
641 + hasMemoCacheFunctionImport(
642 + program,
643 + getReactCompilerRuntimeModule(pass.opts),
644 + )
645 + ) {
646 return true;
647 }
648 return false;
@@ -1126,3 +1129,31 @@ function checkFunctionReferencedBeforeDeclarationAtTopLevel(
1129
1130 return errors.details.length > 0 ? errors : null;
1131 }
1132 +
1133 +type ReactCompilerRuntimeModule =
1134 + | 'react/compiler-runtime' // from react namespace
1135 + | 'react-compiler-runtime'; // npm package
1136 +function getReactCompilerRuntimeModule(
1137 + opts: PluginOptions,
1138 +): ReactCompilerRuntimeModule {
1139 + let moduleName: ReactCompilerRuntimeModule | null = null;
1140 + switch (opts.target) {
1141 + case '17':
1142 + case '18': {
1143 + moduleName = 'react-compiler-runtime';
1144 + break;
1145 + }
1146 + case '19': {
1147 + moduleName = 'react/compiler-runtime';
1148 + break;
1149 + }
1150 + default:
1151 + CompilerError.invariant(moduleName != null, {
1152 + reason: 'Expected target to already be validated',
1153 + description: null,
1154 + loc: null,
1155 + suggestions: null,
1156 + });
1157 + }
1158 + return moduleName;
1159 +}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/target-flag.expect.md new
+45
@@ -0,0 +1,45 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @target="18"
6 +
7 +function Component() {
8 + return <div>Hello world</div>;
9 +}
10 +
11 +export const FIXTURE_ENTRYPOINT = {
12 + fn: Component,
13 + params: [],
14 + isComponent: true,
15 +};
16 +
17 +```
18 +
19 +## Code
20 +
21 +```javascript
22 +import { c as _c } from "react-compiler-runtime"; // @target="18"
23 +
24 +function Component() {
25 + const $ = _c(1);
26 + let t0;
27 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
28 + t0 = <div>Hello world</div>;
29 + $[0] = t0;
30 + } else {
31 + t0 = $[0];
32 + }
33 + return t0;
34 +}
35 +
36 +export const FIXTURE_ENTRYPOINT = {
37 + fn: Component,
38 + params: [],
39 + isComponent: true,
40 +};
41 +
42 +```
43 +
44 +### Eval output
45 +(kind: ok) <div>Hello world</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/target-flag.js new
+11
@@ -0,0 +1,11 @@
1 +// @target="18"
2 +
3 +function Component() {
4 + return <div>Hello world</div>;
5 +}
6 +
7 +export const FIXTURE_ENTRYPOINT = {
8 + fn: Component,
9 + params: [],
10 + isComponent: true,
11 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/userspace-use-memo-cache.expect.md
+14 -6
@@ -2,7 +2,9 @@
2 ## Input
3
4 ```javascript
5 -// @runtimeModule="react-forget-runtime"
5 +// @runtimeModule="react-compiler-runtime"
6 +import {useState} from 'react';
7 +
8 function Component(props) {
9 const [x, setX] = useState(1);
10 let y;
@@ -10,10 +12,12 @@ function Component(props) {
12 y = x * 2;
13 }
14 return (
13 - <Button
15 + <button
16 onClick={() => {
17 setX(10 * y);
16 - }}></Button>
18 + }}>
19 + Click me
20 + </button>
21 );
22 }
23
@@ -28,7 +32,9 @@ export const FIXTURE_ENTRYPOINT = {
32 ## Code
33
34 ```javascript
31 -import { c as _c } from "react-forget-runtime"; // @runtimeModule="react-forget-runtime"
35 +import { c as _c } from "react/compiler-runtime"; // @runtimeModule="react-compiler-runtime"
36 +import { useState } from "react";
37 +
38 function Component(props) {
39 const $ = _c(5);
40 const [x, setX] = useState(1);
@@ -48,11 +54,13 @@ function Component(props) {
54 let t1;
55 if ($[3] !== t0) {
56 t1 = (
51 - <Button
57 + <button
58 onClick={() => {
59 setX(10 * y);
60 }}
55 - />
61 + >
62 + Click me
63 + </button>
64 );
65 $[3] = t0;
66 $[4] = t1;
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/userspace-use-memo-cache.js
+7 -3
@@ -1,4 +1,6 @@
1 -// @runtimeModule="react-forget-runtime"
1 +// @runtimeModule="react-compiler-runtime"
2 +import {useState} from 'react';
3 +
4 function Component(props) {
5 const [x, setX] = useState(1);
6 let y;
@@ -6,10 +8,12 @@ function Component(props) {
8 y = x * 2;
9 }
10 return (
9 - <Button
11 + <button
12 onClick={() => {
13 setX(10 * y);
12 - }}></Button>
14 + }}>
15 + Click me
16 + </button>
17 );
18 }
19