diff --git a/compiler/apps/playground/lib/defaultStore.ts b/compiler/apps/playground/lib/defaultStore.ts index bb33c1b76c539..2baada0b8179a 100644 --- a/compiler/apps/playground/lib/defaultStore.ts +++ b/compiler/apps/playground/lib/defaultStore.ts @@ -18,7 +18,7 @@ import type { PluginOptions } from 'babel-plugin-react-compiler/dist'; ({ //compilationMode: "all" -} satisfies Partial);`; +} satisfies PluginOptions);`; export const defaultStore: Store = { source: index, diff --git a/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts b/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts index dbcec18adf49e..d7960f7e612b6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Babel/RunReactCompilerBabelPlugin.ts @@ -17,7 +17,7 @@ export function runBabelPluginReactCompiler( text: string, file: string, language: 'flow' | 'typescript', - options: Partial | null, + options: PluginOptions | null, includeAst: boolean = false, ): BabelCore.BabelFileResult { const ast = BabelParser.parse(text, { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts index 9b0db75912ecf..c4f665720b4ca 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts @@ -18,7 +18,7 @@ import { import {getOrInsertWith} from '../Utils/utils'; import {ExternalFunction, isHookName} from '../HIR/Environment'; import {Err, Ok, Result} from '../Utils/Result'; -import {LoggerEvent, PluginOptions} from './Options'; +import {LoggerEvent, ParsedPluginOptions} from './Options'; import {BabelFn, getReactCompilerRuntimeModule} from './Program'; import {SuppressionRange} from './Suppression'; @@ -56,7 +56,7 @@ export function validateRestrictedImports( type ProgramContextOptions = { program: NodePath; suppressions: Array; - opts: PluginOptions; + opts: ParsedPluginOptions; filename: string | null; code: string | null; hasModuleScopeOptOut: boolean; @@ -66,7 +66,7 @@ export class ProgramContext { * Program and environment context */ scope: BabelScope; - opts: PluginOptions; + opts: ParsedPluginOptions; filename: string | null; code: string | null; reactRuntimeModule: string; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts index 1ebdb68f9501e..450972a460710 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts @@ -51,8 +51,8 @@ const CustomOptOutDirectiveSchema = z .default(null); type CustomOptOutDirective = z.infer; -export type PluginOptions = { - environment: EnvironmentConfig; +export type PluginOptions = Partial<{ + environment: Partial; logger: Logger | null; @@ -166,7 +166,11 @@ export type PluginOptions = { * a userspace approximation of runtime APIs. */ target: CompilerReactTarget; -}; +}>; + +export type ParsedPluginOptions = Required< + Omit +> & {environment: EnvironmentConfig}; const CompilerReactTargetSchema = z.union([ z.literal('17'), @@ -282,7 +286,7 @@ export type Logger = { debugLogIRs?: (value: CompilerPipelineValue) => void; }; -export const defaultOptions: PluginOptions = { +export const defaultOptions: ParsedPluginOptions = { compilationMode: 'infer', panicThreshold: 'none', environment: parseEnvironmentConfig({}).unwrap(), @@ -299,9 +303,9 @@ export const defaultOptions: PluginOptions = { enableReanimatedCheck: true, customOptOutDirectives: null, target: '19', -} as const; +}; -export function parsePluginOptions(obj: unknown): PluginOptions { +export function parsePluginOptions(obj: unknown): ParsedPluginOptions { if (obj == null || typeof obj !== 'object') { return defaultOptions; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts index 0d7f2f4a4c793..accecc91a29f8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts @@ -23,7 +23,11 @@ import { ProgramContext, validateRestrictedImports, } from './Imports'; -import {CompilerReactTarget, PluginOptions} from './Options'; +import { + CompilerReactTarget, + ParsedPluginOptions, + PluginOptions, +} from './Options'; import {compileFn} from './Pipeline'; import { filterSuppressionsThatAffectFunction, @@ -34,7 +38,7 @@ import {GeneratedSource} from '../HIR'; import {Err, Ok, Result} from '../Utils/Result'; export type CompilerPass = { - opts: PluginOptions; + opts: ParsedPluginOptions; filename: string | null; comments: Array; code: string | null; @@ -45,7 +49,7 @@ const DYNAMIC_GATING_DIRECTIVE = new RegExp('^use memo if\\(([^\\)]*)\\)$'); export function tryFindDirectiveEnablingMemoization( directives: Array, - opts: PluginOptions, + opts: ParsedPluginOptions, ): Result { const optIn = directives.find(directive => OPT_IN_DIRECTIVES.has(directive.value.value), @@ -81,7 +85,7 @@ export function findDirectiveDisablingMemoization( } function findDirectivesDynamicGating( directives: Array, - opts: PluginOptions, + opts: ParsedPluginOptions, ): Result< { gating: ExternalFunction; diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts index 4f8a3e709d1c1..6c54476200a18 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts @@ -7,7 +7,7 @@ import type * as BabelCore from '@babel/core'; import {hasOwnProperty} from '../Utils/utils'; -import {PluginOptions} from './Options'; +import {ParsedPluginOptions} from './Options'; function hasModule(name: string): boolean { if (typeof require === 'undefined') { @@ -52,7 +52,9 @@ export function pipelineUsesReanimatedPlugin( return hasModule('react-native-reanimated'); } -export function injectReanimatedFlag(options: PluginOptions): PluginOptions { +export function injectReanimatedFlag( + options: ParsedPluginOptions, +): ParsedPluginOptions { return { ...options, environment: { diff --git a/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts b/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts index cfa8cf2910fe0..b28879f369ada 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts @@ -175,7 +175,7 @@ function parseConfigPragmaEnvironmentForTest( }); } -const testComplexPluginOptionDefaults: Partial = { +const testComplexPluginOptionDefaults: PluginOptions = { gating: { source: 'ReactForgetFeatureFlag', importSpecifierName: 'isForgetEnabled_Fixtures', diff --git a/compiler/packages/eslint-plugin-react-compiler/src/shared/RunReactCompiler.ts b/compiler/packages/eslint-plugin-react-compiler/src/shared/RunReactCompiler.ts index e8661d7f96c0b..f11d0b910d468 100644 --- a/compiler/packages/eslint-plugin-react-compiler/src/shared/RunReactCompiler.ts +++ b/compiler/packages/eslint-plugin-react-compiler/src/shared/RunReactCompiler.ts @@ -24,7 +24,7 @@ import * as HermesParser from 'hermes-parser'; import {isDeepStrictEqual} from 'util'; import type {ParseResult} from '@babel/parser'; -const COMPILER_OPTIONS: Partial = { +const COMPILER_OPTIONS: PluginOptions = { noEmit: true, panicThreshold: 'none', // Don't emit errors on Flow suppressions--Flow already gave a signal diff --git a/compiler/packages/react-compiler-healthcheck/src/checks/reactCompiler.ts b/compiler/packages/react-compiler-healthcheck/src/checks/reactCompiler.ts index 309454851289f..4e1a193e53acc 100644 --- a/compiler/packages/react-compiler-healthcheck/src/checks/reactCompiler.ts +++ b/compiler/packages/react-compiler-healthcheck/src/checks/reactCompiler.ts @@ -46,7 +46,7 @@ const logger = { }, }; -const COMPILER_OPTIONS: Partial = { +const COMPILER_OPTIONS: PluginOptions = { noEmit: true, compilationMode: 'infer', panicThreshold: 'critical_errors', @@ -72,7 +72,7 @@ function runBabelPluginReactCompiler( text: string, file: string, language: 'flow' | 'typescript', - options: Partial | null, + options: PluginOptions | null, ): BabelCore.BabelFileResult { const ast = BabelParser.parse(text, { sourceFilename: file, diff --git a/compiler/packages/react-mcp-server/src/compiler/index.ts b/compiler/packages/react-mcp-server/src/compiler/index.ts index 0da206bd02eaa..96af7a182bd9f 100644 --- a/compiler/packages/react-mcp-server/src/compiler/index.ts +++ b/compiler/packages/react-mcp-server/src/compiler/index.ts @@ -27,7 +27,7 @@ export type PrintedCompilerPipelineValue = type CompileOptions = { text: string; file: string; - options: Partial | null; + options: PluginOptions | null; }; export async function compile({ text, diff --git a/compiler/packages/react-mcp-server/src/index.ts b/compiler/packages/react-mcp-server/src/index.ts index 2871027d64ce3..9c47346b3c7f8 100644 --- a/compiler/packages/react-mcp-server/src/index.ts +++ b/compiler/packages/react-mcp-server/src/index.ts @@ -145,7 +145,7 @@ server.tool( } }; const errors: Array<{message: string; loc: SourceLocation | null}> = []; - const compilerOptions: Partial = { + const compilerOptions: PluginOptions = { panicThreshold: 'none', logger: { debugLogIRs: logIR, diff --git a/packages/eslint-plugin-react-hooks/src/shared/RunReactCompiler.ts b/packages/eslint-plugin-react-hooks/src/shared/RunReactCompiler.ts index 72e28b1f488ee..f46528cd606df 100644 --- a/packages/eslint-plugin-react-hooks/src/shared/RunReactCompiler.ts +++ b/packages/eslint-plugin-react-hooks/src/shared/RunReactCompiler.ts @@ -25,12 +25,12 @@ import * as HermesParser from 'hermes-parser'; import {isDeepStrictEqual} from 'util'; import type {ParseResult} from '@babel/parser'; -const COMPILER_OPTIONS: Partial = { +const COMPILER_OPTIONS: PluginOptions = { noEmit: true, panicThreshold: 'none', // Don't emit errors on Flow suppressions--Flow already gave a signal flowSuppressions: false, - environment: validateEnvironmentConfig({ + environment: { validateRefAccessDuringRender: true, validateNoSetStateInRender: true, validateNoSetStateInEffects: true, @@ -43,7 +43,7 @@ const COMPILER_OPTIONS: Partial = { validateNoCapitalizedCalls: [], validateHooksUsage: true, validateNoDerivedComputationsInEffects: true, - }), + }, }; export type UnusedOptOutDirective = { @@ -113,7 +113,7 @@ function runReactCompilerImpl({ userOpts, }: RunParams): RunCacheEntry { // Compat with older versions of eslint - const options: PluginOptions = parsePluginOptions({ + const options = parsePluginOptions({ ...COMPILER_OPTIONS, ...userOpts, environment: {