2014-02-05 19:05:09 +08:00
/ *
MIT License http : //www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @ sokra
* /
function AggressiveMergingPlugin ( options ) {
2015-05-28 00:46:47 +08:00
if ( options !== undefined && typeof options !== "object" || Array . isArray ( options ) ) {
2015-07-21 06:29:53 +08:00
throw new Error ( "Argument should be an options object. To use defaults, pass in nothing.\nFor more info on options, see https://webpack.github.io/docs/list-of-plugins.html" ) ;
2015-05-28 00:46:47 +08:00
}
2014-02-05 19:05:09 +08:00
this . options = options || { } ;
}
module . exports = AggressiveMergingPlugin ;
AggressiveMergingPlugin . prototype . apply = function ( compiler ) {
var options = this . options ;
var minSizeReduce = options . minSizeReduce || 1.5 ;
2015-07-13 06:20:09 +08:00
2014-02-05 19:05:09 +08:00
function getParentsWeight ( chunk ) {
return chunk . parents . map ( function ( p ) {
2016-07-13 17:03:14 +08:00
return p . isInitial ( ) ? options . entryChunkMultiplicator || 10 : 1 ;
2014-02-05 19:05:09 +08:00
} ) . reduce ( function ( a , b ) {
return a + b ;
} , 0 ) ;
}
compiler . plugin ( "compilation" , function ( compilation ) {
2015-07-07 06:11:13 +08:00
compilation . plugin ( "optimize-chunks-advanced" , function ( chunks ) {
2014-02-05 19:05:09 +08:00
var combinations = [ ] ;
chunks . forEach ( function ( a , idx ) {
2016-07-13 17:03:14 +08:00
if ( a . isInitial ( ) ) return ;
2014-02-05 19:05:09 +08:00
for ( var i = 0 ; i < idx ; i ++ ) {
var b = chunks [ i ] ;
2016-07-13 17:03:14 +08:00
if ( b . isInitial ( ) ) continue ;
2014-02-05 19:05:09 +08:00
combinations . push ( [ b , a ] ) ;
}
} ) ;
combinations . forEach ( function ( pair ) {
2015-07-13 06:20:09 +08:00
var a = pair [ 0 ] . size ( {
chunkOverhead : 0
} ) ;
var b = pair [ 1 ] . size ( {
chunkOverhead : 0
} ) ;
var ab = pair [ 0 ] . integratedSize ( pair [ 1 ] , {
chunkOverhead : 0
} ) ;
pair . push ( {
a : a ,
b : b ,
ab : ab
} ) ;
2016-01-19 08:52:28 +08:00
var newSize ;
2014-02-05 19:05:09 +08:00
if ( ab === false ) {
pair . unshift ( false ) ;
} else if ( options . moveToParents ) {
var aOnly = ab - b ;
var bOnly = ab - a ;
var common = a + b - ab ;
2016-01-19 08:52:28 +08:00
newSize = common + getParentsWeight ( pair [ 0 ] ) * aOnly + getParentsWeight ( pair [ 1 ] ) * bOnly ;
2015-07-13 06:20:09 +08:00
pair . push ( {
aOnly : aOnly ,
bOnly : bOnly ,
common : common ,
newSize : newSize
} ) ;
2014-02-05 19:05:09 +08:00
} else {
2016-01-19 08:52:28 +08:00
newSize = ab ;
2014-02-05 19:05:09 +08:00
}
pair . unshift ( ( a + b ) / newSize ) ;
} ) ;
combinations = combinations . filter ( function ( pair ) {
return pair [ 0 ] !== false ;
} ) ;
2015-04-24 05:55:50 +08:00
combinations . sort ( function ( a , b ) {
2014-02-05 19:05:09 +08:00
return b [ 0 ] - a [ 0 ] ;
} ) ;
var pair = combinations [ 0 ] ;
if ( ! pair ) return ;
if ( pair [ 0 ] < minSizeReduce ) return ;
if ( options . moveToParents ) {
var commonModules = pair [ 1 ] . modules . filter ( function ( m ) {
return pair [ 2 ] . modules . indexOf ( m ) >= 0 ;
} ) ;
var aOnlyModules = pair [ 1 ] . modules . filter ( function ( m ) {
return commonModules . indexOf ( m ) < 0 ;
} ) ;
var bOnlyModules = pair [ 2 ] . modules . filter ( function ( m ) {
return commonModules . indexOf ( m ) < 0 ;
} ) ;
aOnlyModules . forEach ( function ( m ) {
pair [ 1 ] . removeModule ( m ) ;
m . removeChunk ( pair [ 1 ] ) ;
pair [ 1 ] . parents . forEach ( function ( c ) {
c . addModule ( m ) ;
m . addChunk ( c ) ;
} ) ;
} ) ;
bOnlyModules . forEach ( function ( m ) {
pair [ 2 ] . removeModule ( m ) ;
m . removeChunk ( pair [ 2 ] ) ;
pair [ 2 ] . parents . forEach ( function ( c ) {
c . addModule ( m ) ;
m . addChunk ( c ) ;
} ) ;
} ) ;
}
if ( pair [ 1 ] . integrate ( pair [ 2 ] , "aggressive-merge" ) ) {
chunks . splice ( chunks . indexOf ( pair [ 2 ] ) , 1 ) ;
2015-07-07 06:11:13 +08:00
return true ;
2014-02-05 19:05:09 +08:00
}
} ) ;
} ) ;
} ;