11require ( 'require-safe' ) ( 'html-webpack-plugin' ) ;
22
3- // Escape a string suitable for using in regex
4- function esc ( string ) {
5- return string ? string . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g , '\\$&' ) : string ;
3+ // Create a regular expression to search for a file by chunk name & extension, including associated source maps
4+ function regex ( chunkName , fileExt ) {
5+ return new RegExp ( `^(?:\\/\\w+\\/|)( ${ chunkName } )(?:.*)(\\. ${ fileExt } )(\\.map|)$` ) ;
66}
77
88class WebpackHashExcludePlugin {
99 options ;
10+ changes = { } ;
1011
1112 constructor ( options ) {
1213 this . options = Object . assign ( {
@@ -16,34 +17,36 @@ class WebpackHashExcludePlugin {
1617 } , options ) ;
1718 }
1819
19- removeAssetsHash ( compilation , callback ) {
20- const renameChunkFiles = ( compilation , index , chunkName , filename , suffix ) => {
21- const reg = new RegExp ( `(${ esc ( chunkName ) } )(?:.*)(\.${ suffix } |\.${ suffix } \.map)$` ) ;
22- const newFilename = filename . replace ( reg , '$1$2' ) ;
23- if ( newFilename === filename ) return ;
24- compilation . chunks [ index ] . files . splice ( index , 1 , newFilename ) ;
25- compilation . assets [ newFilename ] = compilation . assets [ filename ] ;
26- delete compilation . assets [ filename ] ;
27-
20+ removeAssetsHash ( compilation , callback ) {
21+ const matchingChunks = compilation . chunks
22+ . filter ( ( chunk ) => this . options . excludeJs . indexOf ( chunk . name ) > - 1 || this . options . excludeCss . indexOf ( chunk . name ) > - 1 ) ;
23+ matchingChunks . forEach ( ( chunk ) => {
24+ if ( this . options . excludeJs . indexOf ( chunk . name ) > - 1 ) {
25+ this . renameChunkFiles ( chunk , 'js' ) ;
26+ }
27+ if ( this . options . excludeCss . indexOf ( chunk . name ) > - 1 ) {
28+ this . renameChunkFiles ( chunk , 'css' ) ;
29+ }
30+ } ) ;
31+ // compilation.assets & compilation.assetsInfo
32+ for ( let [ oldFileName , newFileName ] of Object . entries ( this . changes ) ) {
33+ compilation . assets [ newFileName ] = compilation . assets [ oldFileName ] ;
34+ delete compilation . assets [ oldFileName ] ;
2835
29- compilation . entrypoints . get ( chunkName ) . chunks . map ( ( chunk ) => {
30- if ( chunk . name === chunkName ) {
31- chunk . files = chunk . files . map ( ( file ) => file . replace ( reg , '$1$2' ) ) ;
32- }
33- } ) ;
34- } ;
36+ compilation . assetsInfo . set ( newFileName , compilation . assetsInfo . get ( oldFileName ) ) ;
37+ compilation . assetsInfo . delete ( oldFileName ) ;
38+ }
39+ callback ( ) ;
40+ }
3541
36- compilation . chunks . forEach ( ( chunk ) => {
37- chunk . files . forEach ( ( filename , index ) => {
38- if ( this . options . excludeJs . indexOf ( chunk . name ) > - 1 && filename . indexOf ( 'js' ) > - 1 ) {
39- renameChunkFiles ( compilation , index , chunk . name , filename , 'js' ) ;
40- }
41- if ( this . options . excludeCss . indexOf ( chunk . name ) > - 1 && filename . indexOf ( 'css' ) > - 1 ) {
42- renameChunkFiles ( compilation , index , chunk . name , filename , 'css' ) ;
43- }
44- } ) ;
42+ renameChunkFiles ( chunk , assetType ) {
43+ chunk . files . forEach ( ( fileName , index ) => {
44+ const newFileName = fileName . replace ( regex ( chunk . name , assetType ) , '$1$2$3' ) ;
45+ if ( newFileName !== fileName ) {
46+ this . changes [ fileName ] = newFileName ;
47+ chunk . files [ index ] = newFileName ;
48+ }
4549 } ) ;
46- callback ( ) ;
4750 }
4851
4952 removeHtmlHash ( compilation , callback ) {
@@ -53,17 +56,15 @@ class WebpackHashExcludePlugin {
5356 let index ;
5457
5558 if ( this . options . excludeJs . indexOf ( chunkName ) > - 1 ) {
56- const reg = new RegExp ( `^(${ esc ( chunkName ) } )(?:.*)(\.js)$` ) ;
5759 index = compilation . body . findIndex ( getIndex ) ;
5860 if ( index > - 1 ) {
59- compilation . body [ index ] . attributes . src = compilation . body [ index ] . attributes . src . replace ( reg , '$1$2' ) ;
61+ compilation . body [ index ] . attributes . src = compilation . body [ index ] . attributes . src . replace ( regex ( chunkName , 'js' ) , ' $1$2$3 ') ;
6062 }
6163 }
6264 if ( this . options . excludeCss . indexOf ( chunkName ) > - 1 ) {
63- const reg = new RegExp ( `^(${ esc ( chunkName ) } )(?:.*)(\.css)$` ) ;
6465 index = compilation . head . findIndex ( getIndex ) ;
6566 if ( index > - 1 ) {
66- compilation . head [ index ] . attributes . href = compilation . head [ index ] . attributes . href . replace ( reg , '$1$2' ) ;
67+ compilation . head [ index ] . attributes . href = compilation . head [ index ] . attributes . href . replace ( regex ( chunkName , 'css' ) , ' $1$2$3 ') ;
6768 }
6869 }
6970 } ;
@@ -72,13 +73,15 @@ class WebpackHashExcludePlugin {
7273 }
7374
7475 apply ( compiler ) {
75- // Remove the has from asset file names
76+ // Remove the hash from asset file names
7677 compiler . hooks . emit . tapAsync ( 'emit' , ( compilation , callback ) => {
7778 this . removeAssetsHash ( compilation , callback ) ;
7879 } ) ;
7980 // Remove the hash value of the corresponding chunk resource file
8081 compiler . hooks . thisCompilation . tap ( 'thisCompilation' , compilation => {
81- const requireEnsure = ( source ) => source . replace ( '__webpack_require__.p' , `'${ compilation . options . output . publicPath } '` ) ;
82+ const requireEnsure = ( source ) => {
83+ source . replace ( '__webpack_require__.p' , `'${ compilation . options . output . publicPath } '` )
84+ } ;
8285 compilation . mainTemplate . hooks . requireEnsure . tap ( 'requireEnsure' , requireEnsure ) ;
8386 } ) ;
8487 // Replace the hash value of the html static resource
0 commit comments