@@ -10,7 +10,10 @@ use turbo_tasks::{
1010use turbo_tasks_env:: EnvMap ;
1111use turbo_tasks_fs:: FileSystemPath ;
1212use turbopack:: module_options:: {
13- module_options_context:: MdxTransformOptions , LoaderRuleItem , OptionWebpackRules ,
13+ module_options_context:: {
14+ ConditionItem , ConditionPath , MdxTransformOptions , OptionWebpackConditions ,
15+ } ,
16+ LoaderRuleItem , OptionWebpackRules ,
1417} ;
1518use turbopack_core:: {
1619 issue:: { Issue , IssueSeverity , IssueStage , OptionStyledString , StyledString } ,
@@ -541,11 +544,57 @@ pub struct TurbopackConfig {
541544 /// This option has been replaced by `rules`.
542545 pub loaders : Option < JsonValue > ,
543546 pub rules : Option < FxIndexMap < RcStr , RuleConfigItemOrShortcut > > ,
547+ #[ turbo_tasks( trace_ignore) ]
548+ pub conditions : Option < FxIndexMap < RcStr , ConfigConditionItem > > ,
544549 pub resolve_alias : Option < FxIndexMap < RcStr , JsonValue > > ,
545550 pub resolve_extensions : Option < Vec < RcStr > > ,
546551 pub module_ids : Option < ModuleIds > ,
547552}
548553
554+ #[ derive( Clone , Debug , PartialEq , Serialize , TraceRawVcs , NonLocalValue ) ]
555+ pub struct ConfigConditionItem ( ConditionItem ) ;
556+
557+ impl < ' de > Deserialize < ' de > for ConfigConditionItem {
558+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
559+ where
560+ D : Deserializer < ' de > ,
561+ {
562+ #[ derive( Deserialize ) ]
563+ struct RegexComponents {
564+ source : RcStr ,
565+ flags : RcStr ,
566+ }
567+
568+ #[ derive( Deserialize ) ]
569+ struct ConfigPath {
570+ path : RegexOrGlob ,
571+ }
572+
573+ #[ derive( Deserialize ) ]
574+ #[ serde( tag = "type" , rename_all = "lowercase" ) ]
575+ enum RegexOrGlob {
576+ Regexp { value : RegexComponents } ,
577+ Glob { value : String } ,
578+ }
579+
580+ let config_path = ConfigPath :: deserialize ( deserializer) ?;
581+ let condition_item = match config_path. path {
582+ RegexOrGlob :: Regexp { value } => {
583+ let regex = turbo_esregex:: EsRegex :: new ( & value. source , & value. flags )
584+ . map_err ( serde:: de:: Error :: custom) ?;
585+ ConditionItem {
586+ path : ConditionPath :: Regex ( regex. resolved_cell ( ) ) ,
587+ }
588+ }
589+ RegexOrGlob :: Glob { value } => ConditionItem {
590+ path : ConditionPath :: Glob ( value. into ( ) ) ,
591+ } ,
592+ } ;
593+
594+ Ok ( ConfigConditionItem ( condition_item) )
595+ }
596+ }
597+
549598#[ derive(
550599 Clone , Debug , PartialEq , Eq , Serialize , Deserialize , TraceRawVcs , NonLocalValue , OperationValue ,
551600) ]
@@ -1065,7 +1114,8 @@ impl NextConfig {
10651114 #[ turbo_tasks:: function]
10661115 pub async fn from_string ( string : Vc < RcStr > ) -> Result < Vc < Self > > {
10671116 let string = string. await ?;
1068- let config: NextConfig = serde_json:: from_str ( & string)
1117+ let mut jdeserializer = serde_json:: Deserializer :: from_str ( & string) ;
1118+ let config: NextConfig = serde_path_to_error:: deserialize ( & mut jdeserializer)
10691119 . with_context ( || format ! ( "failed to parse next.config.js: {}" , string) ) ?;
10701120 Ok ( config. cell ( ) )
10711121 }
@@ -1227,6 +1277,22 @@ impl NextConfig {
12271277 Vc :: cell ( Some ( ResolvedVc :: cell ( rules) ) )
12281278 }
12291279
1280+ #[ turbo_tasks:: function]
1281+ pub fn webpack_conditions ( & self ) -> Vc < OptionWebpackConditions > {
1282+ let Some ( config_conditions) = self . turbopack . as_ref ( ) . and_then ( |t| t. conditions . as_ref ( ) )
1283+ else {
1284+ return Vc :: cell ( None ) ;
1285+ } ;
1286+
1287+ let conditions = FxIndexMap :: from_iter (
1288+ config_conditions
1289+ . iter ( )
1290+ . map ( |( k, v) | ( k. clone ( ) , v. 0 . clone ( ) ) ) ,
1291+ ) ;
1292+
1293+ Vc :: cell ( Some ( ResolvedVc :: cell ( conditions) ) )
1294+ }
1295+
12301296 #[ turbo_tasks:: function]
12311297 pub fn persistent_caching_enabled ( & self ) -> Result < Vc < bool > > {
12321298 Ok ( Vc :: cell (
0 commit comments