1+ const _ = require ( 'lodash' )
2+ require ( 'require-safe' ) ( 'html-webpack-plugin' )
3+
4+ function ChunkHashExclude ( options ) {
5+ this . options = _ . assign ( {
6+ excludeJs : [ ] ,
7+ excludeCss : [ ] ,
8+ publicCssPath : '' ,
9+ cancelHtmlHash : true
10+ } , options )
11+ }
12+ ChunkHashExclude . prototype . cancelAssetsHash = function ( compilation , callback ) {
13+ compilation . chunks . forEach ( ( chunk , i ) => {
14+ chunk . files . forEach ( ( filename , j ) => {
15+ if ( this . options . excludeJs . indexOf ( chunk . name ) > - 1 && filename . indexOf ( 'js' ) > - 1 ) {
16+ let reg = new RegExp ( `(js/)(${ chunk . name } )(.*)(.js|.js.map)` )
17+ if ( filename . replace ( reg , '$1$2$4' ) !== filename ) {
18+ compilation . chunks [ i ] . files . splice ( j , 1 , filename . replace ( reg , '$1$2$4' ) )
19+ compilation . assets [ filename . replace ( reg , '$1$2$4' ) ] = compilation . assets [ filename ]
20+ delete compilation . assets [ filename ]
21+ }
22+ }
23+ if ( filename . indexOf ( 'css' ) > - 1 ) {
24+ let reg = new RegExp ( `(css/)(${ chunk . name } )(.*)(.css|.css.map)` )
25+ let newFilename = filename . replace ( reg , '$1$2$4' )
26+ if ( this . options . excludeCss . indexOf ( chunk . name ) > - 1 ) {
27+ if ( newFilename !== filename ) {
28+ compilation . chunks [ i ] . files . splice ( j , 1 , newFilename )
29+ compilation . assets [ newFilename ] = compilation . assets [ filename ]
30+ delete compilation . assets [ filename ]
31+ }
32+ }
33+ }
34+ } )
35+ } )
36+ callback ( )
37+ }
38+
39+ ChunkHashExclude . prototype . cancelHtmlHash = function ( compilation , callback ) {
40+ compilation . chunks . map ( chunk => {
41+ if ( this . options . excludeJs . indexOf ( chunk . names [ 0 ] ) > - 1 ) {
42+ let reg = new RegExp ( `(js/)(${ chunk . names [ 0 ] } )(.*)(.js)` )
43+ let index = - 1
44+ compilation . body . some ( ( item , i ) => {
45+ if ( item . attributes . src . indexOf ( chunk . names [ 0 ] ) > - 1 ) {
46+ index = i
47+ return true
48+ }
49+ return false
50+ } )
51+ if ( index > - 1 ) compilation . body [ index ] . attributes . src = compilation . body [ index ] . attributes . src . replace ( reg , '$1$2$4' )
52+ }
53+ if ( this . options . excludeCss . indexOf ( chunk . names [ 0 ] ) > - 1 ) {
54+ let reg = new RegExp ( `(css/)(${ chunk . names [ 0 ] } )(.*)(.css)` )
55+ let index = - 1
56+ compilation . head . some ( ( item , i ) => {
57+ if ( item . attributes . href . indexOf ( chunk . names [ 0 ] ) > - 1 ) {
58+ index = i
59+ return true
60+ }
61+ return false
62+ } )
63+ if ( index > - 1 ) compilation . head [ index ] . attributes . href = compilation . head [ index ] . attributes . href . replace ( reg , '$1$2$4' )
64+ }
65+ } )
66+ callback ( )
67+ }
68+ // 去掉html模版里面对应chunk资源文件的hash值
69+ ChunkHashExclude . prototype . apply = function ( compiler ) {
70+ if ( compiler . hooks ) {
71+ if ( this . options . publicCssPath ) {
72+ compiler . hooks . thisCompilation . tap ( 'thisCompilation' , compilation => {
73+ compilation . mainTemplate . hooks . requireEnsure . tap ( 'requireEnsure' , ( source , chunk , hash ) => {
74+ return source . replace ( '__webpack_require__.p' , "'" + this . options . publicCssPath + "'" )
75+ } )
76+ } )
77+ }
78+ compiler . hooks . emit . tapAsync ( 'emit' , ( compilation , callback ) => {
79+ this . cancelAssetsHash ( compilation , callback )
80+ } )
81+ // 替换html静态资源的hash值
82+ if ( this . options . cancelHtmlHash ) {
83+ compiler . hooks . compilation . tap ( 'compilation' , ( compilation ) => {
84+ compilation . hooks . htmlWebpackPluginAlterAssetTags . tapAsync ( 'compilation' , ( compilation , callback ) => {
85+ this . cancelHtmlHash ( compilation , callback )
86+ } )
87+ } )
88+ }
89+ } else {
90+ compiler . plugin ( 'emit' , ( compilation , callback ) => {
91+ cancelAssetsHash ( compilation , callback )
92+ } )
93+ if ( this . options . cancelHtmlHash ) {
94+ compiler . plugin ( 'html-webpack-plugin-alter-asset-tags' , ( compilation , callback ) => {
95+ cancelHtmlHash ( compilation , callback )
96+ } )
97+ }
98+ if ( this . options . publicCssPath ) {
99+ compiler . plugin ( 'this-compilation' , compilation => {
100+ compilation . mainTemplate . plugin ( 'require-ensure' , ( source , chunk , hash ) => {
101+ return source . replace ( '__webpack_require__.p' , "'" + this . options . publicCssPath + "'" )
102+ } )
103+ } )
104+ }
105+ }
106+ }
107+
108+ module . exports = ChunkHashExclude
0 commit comments