@@ -12,25 +12,44 @@ import {
12
12
13
13
export default class AddAssetHtmlPlugin {
14
14
constructor ( assets = [ ] ) {
15
- this . assets = Array . isArray ( assets )
16
- ? assets . slice ( ) . reverse ( )
17
- : [ assets ] . filter ( Boolean ) ;
15
+ this . assets = Array . isArray ( assets ) ? assets . slice ( ) . reverse ( ) : [ assets ] ;
16
+ this . addedAssets = [ ] ;
18
17
}
19
18
20
19
/* istanbul ignore next: this would be integration tests */
21
20
apply ( compiler ) {
22
21
compiler . hooks . compilation . tap ( 'AddAssetHtmlPlugin' , compilation => {
23
- let hook ;
22
+ let beforeGenerationHook ;
23
+ let alterAssetTagsHook ;
24
24
25
25
if ( HtmlWebpackPlugin . version === 4 ) {
26
- hook = HtmlWebpackPlugin . getHooks ( compilation ) . beforeAssetTagGeneration ;
26
+ const hooks = HtmlWebpackPlugin . getHooks ( compilation ) ;
27
+
28
+ beforeGenerationHook = hooks . beforeAssetTagGeneration ;
29
+ alterAssetTagsHook = hooks . alterAssetTags ;
27
30
} else {
28
- hook = compilation . hooks . htmlWebpackPluginBeforeHtmlGeneration ;
31
+ const { hooks } = compilation ;
32
+
33
+ beforeGenerationHook = hooks . htmlWebpackPluginBeforeHtmlGeneration ;
34
+ alterAssetTagsHook = hooks . htmlWebpackPluginAlterAssetTags ;
29
35
}
30
36
31
- hook . tapPromise ( 'AddAssetHtmlPlugin' , htmlPluginData =>
37
+ beforeGenerationHook . tapPromise ( 'AddAssetHtmlPlugin' , htmlPluginData =>
32
38
this . addAllAssetsToCompilation ( compilation , htmlPluginData ) ,
33
39
) ;
40
+
41
+ alterAssetTagsHook . tap ( 'AddAssetHtmlPlugin' , htmlPluginData => {
42
+ const { assetTags } = htmlPluginData ;
43
+ if ( assetTags ) {
44
+ this . alterAssetsAttributes ( assetTags ) ;
45
+ } else {
46
+ this . alterAssetsAttributes ( {
47
+ scripts : htmlPluginData . body
48
+ . concat ( htmlPluginData . head )
49
+ . filter ( ( { tagName } ) => tagName === 'script' ) ,
50
+ } ) ;
51
+ }
52
+ } ) ;
34
53
} ) ;
35
54
}
36
55
@@ -42,7 +61,19 @@ export default class AddAssetHtmlPlugin {
42
61
return htmlPluginData ;
43
62
}
44
63
45
- // eslint-disable-next-line class-methods-use-this
64
+ alterAssetsAttributes ( assetTags ) {
65
+ this . assets
66
+ . filter (
67
+ asset => asset . attributes && Object . keys ( asset . attributes ) . length > 0 ,
68
+ )
69
+ . forEach ( asset => {
70
+ assetTags . scripts
71
+ . map ( ( { attributes } ) => attributes )
72
+ . filter ( attrs => this . addedAssets . includes ( attrs . src ) )
73
+ . forEach ( attrs => Object . assign ( attrs , asset . attributes ) ) ;
74
+ } ) ;
75
+ }
76
+
46
77
async addFileToAssets (
47
78
compilation ,
48
79
htmlPluginData ,
@@ -96,6 +127,8 @@ export default class AddAssetHtmlPlugin {
96
127
97
128
resolveOutput ( compilation , addedFilename , outputPath ) ;
98
129
130
+ this . addedAssets . push ( resolvedPath ) ;
131
+
99
132
if ( includeRelatedFiles ) {
100
133
const relatedFiles = await globby ( `${ filepath } .*` ) ;
101
134
await Promise . all (
0 commit comments