@@ -14,6 +14,7 @@ import {
1414 parseEnvironmentConfig ,
1515} from '../HIR/Environment' ;
1616import { hasOwnProperty } from '../Utils/utils' ;
17+ import { fromZodError } from 'zod-validation-error' ;
1718
1819const PanicThresholdOptionsSchema = z . enum ( [
1920 /*
@@ -86,17 +87,6 @@ export type PluginOptions = {
8687 */
8788 compilationMode : CompilationMode ;
8889
89- /*
90- * If enabled, Forget will import `useMemoCache` from the given module
91- * instead of `react/compiler-runtime`.
92- *
93- * ```
94- * // If set to "react-compiler-runtime"
95- * import {c as useMemoCache} from 'react-compiler-runtime';
96- * ```
97- */
98- runtimeModule ?: string | null | undefined ;
99-
10090 /**
10191 * By default React Compiler will skip compilation of code that suppresses the default
10292 * React ESLint rules, since this is a strong indication that the code may be breaking React rules
@@ -121,8 +111,19 @@ export type PluginOptions = {
121111 * Set this flag (on by default) to automatically check for this library and activate the support.
122112 */
123113 enableReanimatedCheck : boolean ;
114+
115+ /**
116+ * The minimum major version of React that the compiler should emit code for. If the target is 19
117+ * or higher, the compiler emits direct imports of React runtime APIs needed by the compiler. On
118+ * versions prior to 19, an extra runtime package react-compiler-runtime is necessary to provide
119+ * a userspace approximation of runtime APIs.
120+ */
121+ target : CompilerReactTarget ;
124122} ;
125123
124+ const CompilerReactTargetSchema = z . enum ( [ '17' , '18' , '19' ] ) ;
125+ export type CompilerReactTarget = z . infer < typeof CompilerReactTargetSchema > ;
126+
126127const CompilationModeSchema = z . enum ( [
127128 /*
128129 * Compiles functions annotated with "use forget" or component/hook-like functions.
@@ -202,14 +203,14 @@ export const defaultOptions: PluginOptions = {
202203 logger : null ,
203204 gating : null ,
204205 noEmit : false ,
205- runtimeModule : null ,
206206 eslintSuppressionRules : null ,
207207 flowSuppressions : true ,
208208 ignoreUseNoForget : false ,
209209 sources : filename => {
210210 return filename . indexOf ( 'node_modules' ) === - 1 ;
211211 } ,
212212 enableReanimatedCheck : true ,
213+ target : '19' ,
213214} as const ;
214215
215216export function parsePluginOptions ( obj : unknown ) : PluginOptions {
@@ -222,25 +223,49 @@ export function parsePluginOptions(obj: unknown): PluginOptions {
222223 // normalize string configs to be case insensitive
223224 value = value . toLowerCase ( ) ;
224225 }
225- if ( key === 'environment' ) {
226- const environmentResult = parseEnvironmentConfig ( value ) ;
227- if ( environmentResult . isErr ( ) ) {
228- CompilerError . throwInvalidConfig ( {
229- reason :
230- 'Error in validating environment config. This is an advanced setting and not meant to be used directly' ,
231- description : environmentResult . unwrapErr ( ) . toString ( ) ,
232- suggestions : null ,
233- loc : null ,
234- } ) ;
226+ if ( isCompilerFlag ( key ) ) {
227+ switch ( key ) {
228+ case 'environment' : {
229+ const environmentResult = parseEnvironmentConfig ( value ) ;
230+ if ( environmentResult . isErr ( ) ) {
231+ CompilerError . throwInvalidConfig ( {
232+ reason :
233+ 'Error in validating environment config. This is an advanced setting and not meant to be used directly' ,
234+ description : environmentResult . unwrapErr ( ) . toString ( ) ,
235+ suggestions : null ,
236+ loc : null ,
237+ } ) ;
238+ }
239+ parsedOptions [ key ] = environmentResult . unwrap ( ) ;
240+ break ;
241+ }
242+ case 'target' : {
243+ parsedOptions [ key ] = parseTargetConfig ( value ) ;
244+ break ;
245+ }
246+ default : {
247+ parsedOptions [ key ] = value ;
248+ }
235249 }
236- parsedOptions [ key ] = environmentResult . unwrap ( ) ;
237- } else if ( isCompilerFlag ( key ) ) {
238- parsedOptions [ key ] = value ;
239250 }
240251 }
241252 return { ...defaultOptions , ...parsedOptions } ;
242253}
243254
255+ export function parseTargetConfig ( value : unknown ) : CompilerReactTarget {
256+ const parsed = CompilerReactTargetSchema . safeParse ( value ) ;
257+ if ( parsed . success ) {
258+ return parsed . data ;
259+ } else {
260+ CompilerError . throwInvalidConfig ( {
261+ reason : 'Not a valid target' ,
262+ description : `${ fromZodError ( parsed . error ) } ` ,
263+ suggestions : null ,
264+ loc : null ,
265+ } ) ;
266+ }
267+ }
268+
244269function isCompilerFlag ( s : string ) : s is keyof PluginOptions {
245270 return hasOwnProperty ( defaultOptions , s ) ;
246271}
0 commit comments