[compiler] Export `PluginOptions` as a type that can be used in input positions (#34550)
Sebastian "Sebbie" Silbermann committed
Sep 22, 2025 at 18:28 UTC
720bb130694169f8d1bf1e8001a2177dd18cdf92
12 files changed
+37
-27
compiler/apps/playground/lib/defaultStore.ts
+1
-1
@@ -18,7 +18,7 @@ import type { PluginOptions } from 'babel-plugin-react-compiler/dist';
18
19
({
20
//compilationMode: "all"
21
-} satisfies Partial<PluginOptions>);`;
21
+} satisfies PluginOptions);`;
22
23
export const defaultStore: Store = {
24
source: index,
compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts
+1
-1
@@ -17,7 +17,7 @@ export function runBabelPluginReactCompiler(
17
text: string,
18
file: string,
19
language: 'flow' | 'typescript',
20
- options: Partial<PluginOptions> | null,
20
+ options: PluginOptions | null,
21
includeAst: boolean = false,
22
): BabelCore.BabelFileResult {
23
const ast = BabelParser.parse(text, {
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts
+3
-3
@@ -18,7 +18,7 @@ import {
18
import {getOrInsertWith} from '../Utils/utils';
19
import {ExternalFunction, isHookName} from '../HIR/Environment';
20
import {Err, Ok, Result} from '../Utils/Result';
21
-import {LoggerEvent, PluginOptions} from './Options';
21
+import {LoggerEvent, ParsedPluginOptions} from './Options';
22
import {BabelFn, getReactCompilerRuntimeModule} from './Program';
23
import {SuppressionRange} from './Suppression';
24
@@ -56,7 +56,7 @@ export function validateRestrictedImports(
56
type ProgramContextOptions = {
57
program: NodePath<t.Program>;
58
suppressions: Array<SuppressionRange>;
59
- opts: PluginOptions;
59
+ opts: ParsedPluginOptions;
60
filename: string | null;
61
code: string | null;
62
hasModuleScopeOptOut: boolean;
@@ -66,7 +66,7 @@ export class ProgramContext {
66
* Program and environment context
67
*/
68
scope: BabelScope;
69
- opts: PluginOptions;
69
+ opts: ParsedPluginOptions;
70
filename: string | null;
71
code: string | null;
72
reactRuntimeModule: string;
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts
+10
-6
@@ -51,8 +51,8 @@ const CustomOptOutDirectiveSchema = z
51
.default(null);
52
type CustomOptOutDirective = z.infer<typeof CustomOptOutDirectiveSchema>;
53
54
-export type PluginOptions = {
55
- environment: EnvironmentConfig;
54
+export type PluginOptions = Partial<{
55
+ environment: Partial<EnvironmentConfig>;
56
57
logger: Logger | null;
58
@@ -166,7 +166,11 @@ export type PluginOptions = {
166
* a userspace approximation of runtime APIs.
167
*/
168
target: CompilerReactTarget;
169
-};
169
+}>;
170
+
171
+export type ParsedPluginOptions = Required<
172
+ Omit<PluginOptions, 'environment'>
173
+> & {environment: EnvironmentConfig};
174
175
const CompilerReactTargetSchema = z.union([
176
z.literal('17'),
@@ -282,7 +286,7 @@ export type Logger = {
286
debugLogIRs?: (value: CompilerPipelineValue) => void;
287
};
288
285
-export const defaultOptions: PluginOptions = {
289
+export const defaultOptions: ParsedPluginOptions = {
290
compilationMode: 'infer',
291
panicThreshold: 'none',
292
environment: parseEnvironmentConfig({}).unwrap(),
@@ -299,9 +303,9 @@ export const defaultOptions: PluginOptions = {
303
enableReanimatedCheck: true,
304
customOptOutDirectives: null,
305
target: '19',
302
-} as const;
306
+};
307
304
-export function parsePluginOptions(obj: unknown): PluginOptions {
308
+export function parsePluginOptions(obj: unknown): ParsedPluginOptions {
309
if (obj == null || typeof obj !== 'object') {
310
return defaultOptions;
311
}
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts
+8
-4
@@ -23,7 +23,11 @@ import {
23
ProgramContext,
24
validateRestrictedImports,
25
} from './Imports';
26
-import {CompilerReactTarget, PluginOptions} from './Options';
26
+import {
27
+ CompilerReactTarget,
28
+ ParsedPluginOptions,
29
+ PluginOptions,
30
+} from './Options';
31
import {compileFn} from './Pipeline';
32
import {
33
filterSuppressionsThatAffectFunction,
@@ -34,7 +38,7 @@ import {GeneratedSource} from '../HIR';
38
import {Err, Ok, Result} from '../Utils/Result';
39
40
export type CompilerPass = {
37
- opts: PluginOptions;
41
+ opts: ParsedPluginOptions;
42
filename: string | null;
43
comments: Array<t.CommentBlock | t.CommentLine>;
44
code: string | null;
@@ -45,7 +49,7 @@ const DYNAMIC_GATING_DIRECTIVE = new RegExp('^use memo if\\(([^\\)]*)\\)$');
49
50
export function tryFindDirectiveEnablingMemoization(
51
directives: Array<t.Directive>,
48
- opts: PluginOptions,
52
+ opts: ParsedPluginOptions,
53
): Result<t.Directive | null, CompilerError> {
54
const optIn = directives.find(directive =>
55
OPT_IN_DIRECTIVES.has(directive.value.value),
@@ -81,7 +85,7 @@ export function findDirectiveDisablingMemoization(
85
}
86
function findDirectivesDynamicGating(
87
directives: Array<t.Directive>,
84
- opts: PluginOptions,
88
+ opts: ParsedPluginOptions,
89
): Result<
90
{
91
gating: ExternalFunction;
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts
+4
-2
@@ -7,7 +7,7 @@
7
8
import type * as BabelCore from '@babel/core';
9
import {hasOwnProperty} from '../Utils/utils';
10
-import {PluginOptions} from './Options';
10
+import {ParsedPluginOptions} from './Options';
11
12
function hasModule(name: string): boolean {
13
if (typeof require === 'undefined') {
@@ -52,7 +52,9 @@ export function pipelineUsesReanimatedPlugin(
52
return hasModule('react-native-reanimated');
53
}
54
55
-export function injectReanimatedFlag(options: PluginOptions): PluginOptions {
55
+export function injectReanimatedFlag(
56
+ options: ParsedPluginOptions,
57
+): ParsedPluginOptions {
58
return {
59
...options,
60
environment: {
compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts
+1
-1
@@ -175,7 +175,7 @@ function parseConfigPragmaEnvironmentForTest(
175
});
176
}
177
178
-const testComplexPluginOptionDefaults: Partial<PluginOptions> = {
178
+const testComplexPluginOptionDefaults: PluginOptions = {
179
gating: {
180
source: 'ReactForgetFeatureFlag',
181
importSpecifierName: 'isForgetEnabled_Fixtures',
compiler/packages/eslint-plugin-react-compiler/src/shared/RunReactCompiler.ts
+1
-1
@@ -24,7 +24,7 @@ import * as HermesParser from 'hermes-parser';
24
import {isDeepStrictEqual} from 'util';
25
import type {ParseResult} from '@babel/parser';
26
27
-const COMPILER_OPTIONS: Partial<PluginOptions> = {
27
+const COMPILER_OPTIONS: PluginOptions = {
28
noEmit: true,
29
panicThreshold: 'none',
30
// Don't emit errors on Flow suppressions--Flow already gave a signal
compiler/packages/react-compiler-healthcheck/src/checks/reactCompiler.ts
+2
-2
@@ -46,7 +46,7 @@ const logger = {
46
},
47
};
48
49
-const COMPILER_OPTIONS: Partial<PluginOptions> = {
49
+const COMPILER_OPTIONS: PluginOptions = {
50
noEmit: true,
51
compilationMode: 'infer',
52
panicThreshold: 'critical_errors',
@@ -72,7 +72,7 @@ function runBabelPluginReactCompiler(
72
text: string,
73
file: string,
74
language: 'flow' | 'typescript',
75
- options: Partial<PluginOptions> | null,
75
+ options: PluginOptions | null,
76
): BabelCore.BabelFileResult {
77
const ast = BabelParser.parse(text, {
78
sourceFilename: file,
compiler/packages/react-mcp-server/src/compiler/index.ts
+1
-1
@@ -27,7 +27,7 @@ export type PrintedCompilerPipelineValue =
27
type CompileOptions = {
28
text: string;
29
file: string;
30
- options: Partial<PluginOptions> | null;
30
+ options: PluginOptions | null;
31
};
32
export async function compile({
33
text,
compiler/packages/react-mcp-server/src/index.ts
+1
-1
@@ -145,7 +145,7 @@ server.tool(
145
}
146
};
147
const errors: Array<{message: string; loc: SourceLocation | null}> = [];
148
- const compilerOptions: Partial<PluginOptions> = {
148
+ const compilerOptions: PluginOptions = {
149
panicThreshold: 'none',
150
logger: {
151
debugLogIRs: logIR,
packages/eslint-plugin-react-hooks/src/shared/RunReactCompiler.ts
+4
-4
@@ -25,12 +25,12 @@ import * as HermesParser from 'hermes-parser';
25
import {isDeepStrictEqual} from 'util';
26
import type {ParseResult} from '@babel/parser';
27
28
-const COMPILER_OPTIONS: Partial<PluginOptions> = {
28
+const COMPILER_OPTIONS: PluginOptions = {
29
noEmit: true,
30
panicThreshold: 'none',
31
// Don't emit errors on Flow suppressions--Flow already gave a signal
32
flowSuppressions: false,
33
- environment: validateEnvironmentConfig({
33
+ environment: {
34
validateRefAccessDuringRender: true,
35
validateNoSetStateInRender: true,
36
validateNoSetStateInEffects: true,
@@ -43,7 +43,7 @@ const COMPILER_OPTIONS: Partial<PluginOptions> = {
43
validateNoCapitalizedCalls: [],
44
validateHooksUsage: true,
45
validateNoDerivedComputationsInEffects: true,
46
- }),
46
+ },
47
};
48
49
export type UnusedOptOutDirective = {
@@ -113,7 +113,7 @@ function runReactCompilerImpl({
113
userOpts,
114
}: RunParams): RunCacheEntry {
115
// Compat with older versions of eslint
116
- const options: PluginOptions = parsePluginOptions({
116
+ const options = parsePluginOptions({
117
...COMPILER_OPTIONS,
118
...userOpts,
119
environment: {