11use async_trait:: async_trait;
2- use rustc_hash:: FxHashSet ;
2+ use rustc_hash:: { FxHashMap , FxHashSet } ;
33
44use super :: * ;
5- use crate :: { cache:: Cache , compilation:: pass:: PassExt , logger:: Logger } ;
5+ use crate :: {
6+ cache:: Cache ,
7+ compilation:: { CompilationChunkAssetHook , pass:: PassExt } ,
8+ logger:: Logger ,
9+ } ;
610
711pub struct CreateChunkAssetsPass ;
812
@@ -114,7 +118,7 @@ pub async fn create_chunk_assets(
114118 let s = unsafe { token. used ( ( compilation_ref, & plugin_driver, chunk) ) } ;
115119
116120 s. spawn ( |( this, plugin_driver, chunk) | async {
117- let mut manifests = Vec :: new ( ) ;
121+ let mut manifests = Vec :: with_capacity ( 2 ) ;
118122 let mut diagnostics = Vec :: new ( ) ;
119123 plugin_driver
120124 . compilation_hooks
@@ -134,12 +138,14 @@ pub async fn create_chunk_assets(
134138 } )
135139 . await ;
136140
137- let mut chunk_render_results = ChunkRenderArtifact :: default ( ) ;
141+ let mut chunk_render_results =
142+ FxHashMap :: with_capacity_and_hasher ( results. len ( ) , Default :: default ( ) ) ;
138143 for result in results {
139144 let item = result. to_rspack_result ( ) ?;
140145 let ( key, value) = item?;
141146 chunk_render_results. insert ( key, value) ;
142147 }
148+ let chunk_render_results = ChunkRenderArtifact :: from ( chunk_render_results) ;
143149 let chunk_ukey_and_manifest = if compilation
144150 . incremental
145151 . passes_enabled ( IncrementalPasses :: CHUNK_ASSET )
@@ -152,6 +158,51 @@ pub async fn create_chunk_assets(
152158 chunk_render_results
153159 } ;
154160
161+ let has_chunk_asset_hook =
162+ has_chunk_asset_taps ( & plugin_driver. compilation_hooks . chunk_asset ) . await ;
163+
164+ if !has_chunk_asset_hook {
165+ for (
166+ chunk_ukey,
167+ ChunkRenderResult {
168+ manifests,
169+ diagnostics,
170+ } ,
171+ ) in chunk_ukey_and_manifest
172+ {
173+ if !diagnostics. is_empty ( ) {
174+ compilation. extend_diagnostics ( diagnostics) ;
175+ }
176+
177+ if manifests. is_empty ( ) {
178+ continue ;
179+ }
180+
181+ let current_chunk = compilation
182+ . build_chunk_graph_artifact
183+ . chunk_by_ukey
184+ . expect_get_mut ( & chunk_ukey) ;
185+
186+ current_chunk. set_rendered ( true ) ;
187+ for file_manifest in & manifests {
188+ if file_manifest. auxiliary {
189+ current_chunk. add_auxiliary_file ( file_manifest. filename . clone ( ) ) ;
190+ } else {
191+ current_chunk. add_file ( file_manifest. filename . clone ( ) ) ;
192+ }
193+ }
194+
195+ for file_manifest in manifests {
196+ compilation. emit_asset (
197+ file_manifest. filename ,
198+ CompilationAsset :: new ( Some ( file_manifest. source ) , file_manifest. info ) ,
199+ ) ;
200+ }
201+ }
202+
203+ return Ok ( ( ) ) ;
204+ }
205+
155206 for (
156207 chunk_ukey,
157208 ChunkRenderResult {
@@ -160,7 +211,13 @@ pub async fn create_chunk_assets(
160211 } ,
161212 ) in chunk_ukey_and_manifest
162213 {
163- compilation. extend_diagnostics ( diagnostics) ;
214+ if !diagnostics. is_empty ( ) {
215+ compilation. extend_diagnostics ( diagnostics) ;
216+ }
217+
218+ if manifests. is_empty ( ) {
219+ continue ;
220+ }
164221
165222 for file_manifest in manifests {
166223 let filename = file_manifest. filename ;
@@ -201,3 +258,20 @@ async fn chunk_asset(
201258 . await ?;
202259 Ok ( ( ) )
203260}
261+
262+ async fn has_chunk_asset_taps ( hook : & CompilationChunkAssetHook ) -> bool {
263+ if !hook. taps . is_empty ( ) {
264+ return true ;
265+ }
266+
267+ for interceptor in hook. interceptors . iter ( ) {
268+ let Ok ( taps) = interceptor. call ( hook) . await else {
269+ return true ;
270+ } ;
271+ if !taps. is_empty ( ) {
272+ return true ;
273+ }
274+ }
275+
276+ false
277+ }
0 commit comments