@@ -55,7 +55,7 @@ use turbopack_core::{
5555 } ,
5656 file_source:: FileSource ,
5757 ident:: { AssetIdent , Layer } ,
58- module:: Module ,
58+ module:: { Module , Modules } ,
5959 module_graph:: {
6060 GraphEntries , ModuleGraph , SingleModuleGraph , VisitedModules ,
6161 binding_usage_info:: compute_binding_usage_info,
@@ -973,7 +973,7 @@ impl AppProject {
973973 pub async fn app_module_graph (
974974 & self ,
975975 rsc_entry : ResolvedVc < Box < dyn Module > > ,
976- server_action_loader_module : ResolvedVc < Box < dyn Module > > ,
976+ server_action_loader_modules : ResolvedVc < Modules > ,
977977 client_shared_entries : Vc < EvaluatableAssets > ,
978978 has_layout_segments : bool ,
979979 ) -> Result < Vc < ModuleGraph > > {
@@ -991,8 +991,14 @@ impl AppProject {
991991 // Implements layout segment optimization to compute a graph "chain" for each layout
992992 // segment
993993 async move {
994- let rsc_entry_chunk_group =
995- ChunkGroupEntry :: Entry ( vec ! [ server_action_loader_module, rsc_entry] ) ;
994+ let rsc_entry_chunk_group = ChunkGroupEntry :: Entry (
995+ server_action_loader_modules
996+ . await ?
997+ . iter ( )
998+ . copied ( )
999+ . chain ( std:: iter:: once ( rsc_entry) )
1000+ . collect ( ) ,
1001+ ) ;
9961002
9971003 let mut graphs = vec ! [ ] ;
9981004 let visited_modules = if has_layout_segments {
@@ -1279,15 +1285,36 @@ impl AppEndpoint {
12791285 }
12801286
12811287 #[ turbo_tasks:: function]
1282- async fn server_action_loader_module ( self : Vc < Self > ) -> Result < Vc < Box < dyn Module > > > {
1288+ async fn server_action_loader_modules ( self : Vc < Self > ) -> Result < Vc < Modules > > {
12831289 let this = self . await ?;
1284- // let app_entry = self.app_endpoint_entry().await?;
1285- // let runtime = app_entry.config.await?.runtime.unwrap_or_default();
1290+ let app_entry = self . app_endpoint_entry ( ) . await ?;
1291+ let runtime = app_entry. config . await ?. runtime . unwrap_or_default ( ) ;
12861292
1287- Ok ( Vc :: upcast ( ServerActionCollectModule :: new (
1288- rcstr ! ( "next/server-actions" ) ,
1289- this. page . to_string ( ) . into ( ) ,
1290- ) ) )
1293+ Ok ( Vc :: cell ( vec ! [
1294+ // Collect inline "use server" function inside of RSC modules
1295+ ResolvedVc :: upcast(
1296+ ServerActionCollectModule :: new(
1297+ rcstr!( "next/server-actions" ) ,
1298+ this. page. to_string( ) . into( ) ,
1299+ )
1300+ . to_resolved( )
1301+ . await ?,
1302+ ) ,
1303+ // Collect "use server" modules imported from client components.
1304+ // By only collecting the correct runtime, modules emitted for the other runtime are
1305+ // never even compiled.
1306+ ResolvedVc :: upcast(
1307+ ServerActionCollectModule :: new(
1308+ match runtime {
1309+ NextRuntime :: NodeJs => rcstr!( "next/server-actions/node" ) ,
1310+ NextRuntime :: Edge => rcstr!( "next/server-actions/edge" ) ,
1311+ } ,
1312+ this. page. to_string( ) . into( ) ,
1313+ )
1314+ . to_resolved( )
1315+ . await ?,
1316+ ) ,
1317+ ] ) )
12911318 }
12921319
12931320 #[ turbo_tasks:: function]
@@ -1342,11 +1369,11 @@ impl AppEndpoint {
13421369
13431370 let is_app_page = matches ! ( this. ty, AppEndpointType :: Page { .. } ) ;
13441371
1345- let server_action_loader = self . server_action_loader_module ( ) ;
1372+ let server_action_loader_modules = self . server_action_loader_modules ( ) ;
13461373
13471374 let module_graph = this. app_project . app_module_graph (
13481375 * rsc_entry,
1349- server_action_loader ,
1376+ server_action_loader_modules ,
13501377 // We only need the client runtime entries for pages not for Route Handlers
13511378 if is_app_page {
13521379 this. app_project . client_runtime_entries ( )
@@ -1547,7 +1574,7 @@ impl AppEndpoint {
15471574 if emit_rsc_manifests {
15481575 server_assets. insert (
15491576 create_server_actions_manifest (
1550- self . server_action_loader_module ( ) ,
1577+ self . server_action_loader_modules ( ) ,
15511578 node_root. clone ( ) ,
15521579 app_entry. original_name . clone ( ) ,
15531580 runtime,
@@ -1864,24 +1891,29 @@ impl AppEndpoint {
18641891 let project = this. app_project . project ( ) ;
18651892 let app_entry = self . app_endpoint_entry ( ) . await ?;
18661893 let runtime = app_entry. config . await ?. runtime . unwrap_or_default ( ) ;
1867- let server_action_loader = self . server_action_loader_module ( ) . to_resolved ( ) . await ?;
1894+ let server_action_loaders = self . server_action_loader_modules ( ) . await ?;
18681895
18691896 let chunking_context = project. runtime_chunking_context ( process_client_assets, runtime) ;
18701897
1898+ let entry_chunk_group = ChunkGroup :: Entry (
1899+ server_action_loaders
1900+ . iter ( )
1901+ . copied ( )
1902+ . chain ( std:: iter:: once ( app_entry. rsc_entry ) )
1903+ . collect ( ) ,
1904+ ) ;
1905+
18711906 Ok ( match runtime {
18721907 NextRuntime :: Edge => chunking_context. evaluated_chunk_group_assets (
18731908 app_entry. rsc_entry . ident ( ) ,
1874- ChunkGroup :: Entry ( vec ! [ server_action_loader , app_entry . rsc_entry ] ) ,
1909+ entry_chunk_group ,
18751910 module_graph,
18761911 AvailabilityInfo :: root ( ) ,
18771912 ) ,
18781913 NextRuntime :: NodeJs => {
18791914 async {
18801915 let mut current_chunk_group = ChunkGroupResult :: empty_resolved ( ) ;
18811916
1882- let entry_chunk_group =
1883- ChunkGroup :: Entry ( vec ! [ server_action_loader, app_entry. rsc_entry] ) ;
1884-
18851917 let chunk_group_info = module_graph. chunk_group_info ( ) ;
18861918
18871919 let client_references = client_references. await ?;
@@ -2138,10 +2170,14 @@ impl Endpoint for AppEndpoint {
21382170 async fn entries ( self : Vc < Self > ) -> Result < Vc < GraphEntries > > {
21392171 let this = self . await ?;
21402172 Ok ( Vc :: cell ( vec ! [
2141- ChunkGroupEntry :: Entry ( vec![
2142- self . server_action_loader_module( ) . to_resolved( ) . await ?,
2143- self . app_endpoint_entry( ) . await ?. rsc_entry,
2144- ] ) ,
2173+ ChunkGroupEntry :: Entry (
2174+ self . server_action_loader_modules( )
2175+ . await ?
2176+ . iter( )
2177+ . copied( )
2178+ . chain( std:: iter:: once( self . app_endpoint_entry( ) . await ?. rsc_entry) )
2179+ . collect( ) ,
2180+ ) ,
21452181 ChunkGroupEntry :: Entry (
21462182 this. app_project
21472183 . client_runtime_entries( )
@@ -2158,12 +2194,12 @@ impl Endpoint for AppEndpoint {
21582194 async fn module_graphs ( self : Vc < Self > ) -> Result < Vc < ModuleGraphs > > {
21592195 let this = self . await ?;
21602196 let app_entry = self . app_endpoint_entry ( ) . await ?;
2161- let server_action_loader = self . server_action_loader_module ( ) ;
2197+ let server_action_loader_modules = self . server_action_loader_modules ( ) ;
21622198 let module_graph = this
21632199 . app_project
21642200 . app_module_graph (
21652201 * app_entry. rsc_entry ,
2166- server_action_loader ,
2202+ server_action_loader_modules ,
21672203 this. app_project . client_runtime_entries ( ) ,
21682204 matches ! ( this. ty, AppEndpointType :: Page { .. } ) ,
21692205 )
0 commit comments