@@ -9,8 +9,6 @@ import { AssertNever } from './type-assert'
99
1010const unsupportedHookName = [
1111 'augmentChunkHash' ,
12- 'banner' ,
13- 'footer' ,
1412 'generateBundle' ,
1513 'moduleParsed' ,
1614 'onLog' ,
@@ -23,8 +21,6 @@ const unsupportedHookName = [
2321 // FIXME: Conflict with the `skip` option in `PluginContext#resolve`. Since we can't detect it in advance,
2422 // we have to bailout all plugins with `resolveId` hook.
2523 'resolveId' ,
26- 'intro' ,
27- 'outro' ,
2824] as const
2925const unsupportedHooks : Set < string > = new Set ( unsupportedHookName )
3026
@@ -108,6 +104,16 @@ function createComposedPlugin(plugins: Plugin[]): Plugin {
108104 }
109105 break
110106 }
107+ case 'banner' :
108+ case 'footer' :
109+ case 'intro' :
110+ case 'outro' : {
111+ const hook = plugin [ pluginProp ]
112+ if ( hook ) {
113+ ; ( batchedHooks [ pluginProp ] ??= [ ] ) . push ( hook )
114+ }
115+ break
116+ }
111117 default : {
112118 // All known hooks should be handled above.
113119 // User-defined custom properties will hit this branch and it's ok. Just ignore them.
@@ -236,6 +242,29 @@ function createComposedPlugin(plugins: Plugin[]): Plugin {
236242 }
237243 break
238244 }
245+ case 'banner' :
246+ case 'footer' :
247+ case 'intro' :
248+ case 'outro' : {
249+ const hooks = batchedHooks [ hookName ]
250+ if ( hooks ?. length ) {
251+ composed [ hookName ] = async function ( chunk ) {
252+ const ret : string [ ] = [ ]
253+ for ( const hook of hooks ) {
254+ {
255+ const { handler } = normalizeHook ( hook )
256+ ret . push (
257+ typeof handler === 'string'
258+ ? handler
259+ : await handler . call ( this , chunk ) ,
260+ )
261+ }
262+ }
263+ return ret . join ( '\n' )
264+ }
265+ }
266+ break
267+ }
239268 default : {
240269 // Supported hooks should be handled above, otherwise it should be filtered out in the beginning.
241270 type _ExhaustiveCheck = AssertNever < typeof hookName >
0 commit comments