@@ -45,7 +45,7 @@ use crate::{
4545 origin:: ResolveOrigin ,
4646 parse:: { Request , stringify_data_uri} ,
4747 pattern:: { Pattern , PatternMatch , read_matches} ,
48- plugin:: { AfterResolvePlugin , BeforeResolvePlugin } ,
48+ plugin:: { AfterResolvePlugin , AfterResolvePluginCondition , BeforeResolvePlugin } ,
4949 remap:: { ExportsField , ImportsField , ReplacedSubpathValueResult } ,
5050 } ,
5151 source:: { OptionSource , Source , Sources } ,
@@ -67,6 +67,12 @@ pub use remap::{ResolveAliasMap, SubpathValue};
6767
6868use crate :: { error:: PrettyPrintError , issue:: IssueSeverity } ;
6969
70+ /// Type alias for a resolved after-resolve plugin paired with its condition.
71+ type AfterResolvePluginWithCondition = (
72+ ResolvedVc < Box < dyn AfterResolvePlugin > > ,
73+ Vc < AfterResolvePluginCondition > ,
74+ ) ;
75+
7076#[ turbo_tasks:: value( shared) ]
7177#[ derive( Clone , Debug ) ]
7278pub enum ModuleResolveResultItem {
@@ -1180,7 +1186,8 @@ enum ImportsFieldResult {
11801186#[ turbo_tasks:: function]
11811187async fn imports_field ( lookup_path : FileSystemPath ) -> Result < Vc < ImportsFieldResult > > {
11821188 // We don't need to collect affecting sources here because we don't use them
1183- let package_json_context = find_context_file ( lookup_path, package_json ( ) , false ) . await ?;
1189+ let package_json_context =
1190+ find_context_file ( lookup_path, package_json ( ) . resolve ( ) . await ?, false ) . await ?;
11841191 let FindContextFileResult :: Found ( package_json_path, _refs) = & * package_json_context else {
11851192 return Ok ( ImportsFieldResult :: None . cell ( ) ) ;
11861193 } ;
@@ -1598,13 +1605,24 @@ pub async fn resolve_inline(
15981605 }
15991606
16001607 async {
1601- let before_plugins_result = handle_before_resolve_plugins (
1602- lookup_path. clone ( ) ,
1603- reference_type. clone ( ) ,
1604- request,
1605- options,
1606- )
1607- . await ?;
1608+ // Pre-fetch options once to avoid repeated await calls
1609+ let options_value = options. await ?;
1610+
1611+ // Fast path: skip plugin handling if no plugins are configured
1612+ let has_before_plugins = !options_value. before_resolve_plugins . is_empty ( ) ;
1613+ let has_after_plugins = !options_value. after_resolve_plugins . is_empty ( ) ;
1614+
1615+ let before_plugins_result = if has_before_plugins {
1616+ handle_before_resolve_plugins (
1617+ lookup_path. clone ( ) ,
1618+ reference_type. clone ( ) ,
1619+ request,
1620+ options,
1621+ )
1622+ . await ?
1623+ } else {
1624+ None
1625+ } ;
16081626
16091627 let raw_result = match before_plugins_result {
16101628 Some ( result) => result,
@@ -1615,9 +1633,13 @@ pub async fn resolve_inline(
16151633 }
16161634 } ;
16171635
1618- let result =
1636+ let result = if has_after_plugins {
16191637 handle_after_resolve_plugins ( lookup_path, reference_type, request, options, raw_result)
1620- . await ?;
1638+ . await ?
1639+ } else {
1640+ raw_result
1641+ } ;
1642+
16211643 Ok ( result)
16221644 }
16231645 . instrument ( span)
@@ -1685,7 +1707,9 @@ async fn handle_before_resolve_plugins(
16851707 request : Vc < Request > ,
16861708 options : Vc < ResolveOptions > ,
16871709) -> Result < Option < Vc < ResolveResult > > > {
1688- for plugin in & options. await ?. before_resolve_plugins {
1710+ let options_value = options. await ?;
1711+
1712+ for plugin in & options_value. before_resolve_plugins {
16891713 let condition = plugin. before_resolve_condition ( ) . resolve ( ) . await ?;
16901714 if !* condition. matches ( request) . await ? {
16911715 continue ;
@@ -1709,15 +1733,25 @@ async fn handle_after_resolve_plugins(
17091733 options : Vc < ResolveOptions > ,
17101734 result : Vc < ResolveResult > ,
17111735) -> Result < Vc < ResolveResult > > {
1736+ // Pre-fetch options to avoid repeated await calls in the inner loop
1737+ let options_value = options. await ?;
1738+
1739+ // Pre-resolve all plugin conditions once to avoid repeated resolve calls in the loop
1740+ let mut resolved_conditions: Vec < AfterResolvePluginWithCondition > =
1741+ Vec :: with_capacity ( options_value. after_resolve_plugins . len ( ) ) ;
1742+ for plugin in & options_value. after_resolve_plugins {
1743+ let condition = plugin. after_resolve_condition ( ) . resolve ( ) . await ?;
1744+ resolved_conditions. push ( ( * plugin, condition) ) ;
1745+ }
1746+
17121747 async fn apply_plugins_to_path (
17131748 path : FileSystemPath ,
17141749 lookup_path : FileSystemPath ,
17151750 reference_type : ReferenceType ,
17161751 request : Vc < Request > ,
1717- options : Vc < ResolveOptions > ,
1752+ plugins_with_conditions : & [ AfterResolvePluginWithCondition ] ,
17181753 ) -> Result < Option < Vc < ResolveResult > > > {
1719- for plugin in & options. await ?. after_resolve_plugins {
1720- let after_resolve_condition = plugin. after_resolve_condition ( ) . resolve ( ) . await ?;
1754+ for ( plugin, after_resolve_condition) in plugins_with_conditions {
17211755 if * after_resolve_condition. matches ( path. clone ( ) ) . await ?
17221756 && let Some ( result) = * plugin
17231757 . after_resolve (
@@ -1748,7 +1782,7 @@ async fn handle_after_resolve_plugins(
17481782 lookup_path. clone ( ) ,
17491783 reference_type. clone ( ) ,
17501784 request,
1751- options ,
1785+ & resolved_conditions ,
17521786 )
17531787 . await ?
17541788 {
@@ -2646,7 +2680,8 @@ enum FindSelfReferencePackageResult {
26462680async fn find_self_reference (
26472681 lookup_path : FileSystemPath ,
26482682) -> Result < Vc < FindSelfReferencePackageResult > > {
2649- let package_json_context = find_context_file ( lookup_path, package_json ( ) , false ) . await ?;
2683+ let package_json_context =
2684+ find_context_file ( lookup_path, package_json ( ) . resolve ( ) . await ?, false ) . await ?;
26502685 if let FindContextFileResult :: Found ( package_json_path, _refs) = & * package_json_context {
26512686 let read =
26522687 read_package_json ( Vc :: upcast ( FileSource :: new ( package_json_path. clone ( ) ) ) ) . await ?;
0 commit comments