2013-12-03 16:27:15 +08:00
/ *
MIT License http : //www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @ sokra
* /
2015-01-12 06:15:11 +08:00
function CommonsChunkPlugin ( options , filenameTemplate , selectedChunks , minChunks ) {
2015-01-18 07:50:05 +08:00
if ( options && typeof options === "object" && ! Array . isArray ( options ) ) {
2015-01-12 06:15:11 +08:00
this . chunkNames = options . name || options . names ;
this . filenameTemplate = options . filename ;
this . minChunks = options . minChunks ;
this . selectedChunks = options . chunks ;
if ( options . children ) this . selectedChunks = false ;
this . async = options . async ;
this . minSize = options . minSize ;
} else {
var chunkNames = options ;
if ( typeof filenameTemplate !== "string" && filenameTemplate !== null ) {
minChunks = selectedChunks ;
2015-04-24 05:55:50 +08:00
selectedChunks = filenameTemplate ;
2015-01-12 06:15:11 +08:00
filenameTemplate = chunkNames ;
}
if ( ! Array . isArray ( selectedChunks ) && typeof selectedChunks !== "boolean" && selectedChunks !== null ) {
minChunks = selectedChunks ;
selectedChunks = undefined ;
}
this . chunkNames = chunkNames ;
this . filenameTemplate = filenameTemplate ;
this . minChunks = minChunks ;
this . selectedChunks = selectedChunks ;
2014-07-19 20:32:48 +08:00
}
2013-12-03 16:27:15 +08:00
}
module . exports = CommonsChunkPlugin ;
CommonsChunkPlugin . prototype . apply = function ( compiler ) {
2014-12-22 19:33:11 +08:00
var chunkNames = this . chunkNames ;
2013-12-03 18:19:30 +08:00
var filenameTemplate = this . filenameTemplate ;
2015-01-12 06:15:11 +08:00
var minChunks = this . minChunks ;
2014-12-22 19:33:11 +08:00
var selectedChunks = this . selectedChunks ;
2015-01-12 06:15:11 +08:00
var async = this . async ;
var minSize = this . minSize ;
2014-07-19 20:32:48 +08:00
compiler . plugin ( "this-compilation" , function ( compilation ) {
2014-09-23 14:42:54 +08:00
compilation . plugin ( [ "optimize-chunks" , "optimize-extracted-chunks" ] , function ( chunks ) {
2015-04-27 04:47:47 +08:00
var commonChunks ;
2015-01-12 06:15:11 +08:00
if ( ! chunkNames && ( selectedChunks === false || async ) ) {
2015-04-27 04:47:47 +08:00
commonChunks = chunks ;
2014-12-22 19:33:11 +08:00
} else if ( Array . isArray ( chunkNames ) ) {
2015-04-29 18:46:00 +08:00
commonChunks = chunkNames . map ( function ( chunkName ) {
return chunks . filter ( function ( chunk ) {
return chunk . name === chunkName ;
} ) [ 0 ] ;
2013-12-03 18:28:39 +08:00
} ) ;
2014-12-22 19:33:11 +08:00
} else {
2015-04-27 04:47:47 +08:00
commonChunks = chunks . filter ( function ( chunk ) {
2014-12-22 19:33:11 +08:00
return chunk . name === chunkNames ;
} ) ;
}
if ( commonChunks . length === 0 ) {
var chunk = this . addChunk ( chunkNames ) ;
chunk . initial = chunk . entry = true ;
commonChunks = [ chunk ] ;
}
2015-04-27 04:47:47 +08:00
commonChunks . forEach ( function processCommonChunk ( commonChunk , idx ) {
2014-12-22 19:33:11 +08:00
var commonModulesCount = [ ] ;
var commonModules = [ ] ;
2015-04-27 04:47:47 +08:00
var usedChunks ;
2014-12-22 19:33:11 +08:00
if ( Array . isArray ( selectedChunks ) ) {
2015-04-27 04:47:47 +08:00
usedChunks = chunks . filter ( function ( chunk ) {
2014-12-22 19:33:11 +08:00
if ( chunk === commonChunk ) return false ;
return selectedChunks . indexOf ( chunk . name ) >= 0 ;
} ) ;
2015-04-27 04:47:47 +08:00
} else if ( selectedChunks === false || async ) {
usedChunks = ( commonChunk . chunks || [ ] ) . filter ( function ( chunk ) {
2014-12-22 19:33:11 +08:00
// we can only move modules from this chunk if the "commonChunk" is the only parent
2015-01-12 06:15:11 +08:00
return async || chunk . parents . length === 1 ;
2014-12-22 19:33:11 +08:00
} ) ;
} else {
2015-04-27 04:47:47 +08:00
if ( ! commonChunk . entry ) {
2015-04-29 18:46:00 +08:00
compilation . errors . push ( new Error ( "CommonsChunkPlugin: While running in normal mode it's not allowed to use a non-entry chunk (" + commonChunk . name + ")" ) ) ;
2015-04-27 04:47:47 +08:00
return ;
}
usedChunks = chunks . filter ( function ( chunk ) {
var found = commonChunks . indexOf ( chunk ) ;
if ( found >= idx ) return false ;
2014-12-22 19:33:11 +08:00
return chunk . entry ;
} ) ;
}
2015-01-12 06:15:11 +08:00
if ( async ) {
var asyncChunk = this . addChunk ( typeof async === "string" ? async : undefined ) ;
asyncChunk . chunkReason = "async commons chunk" ;
asyncChunk . extraAsync = true ;
asyncChunk . addParent ( commonChunk ) ;
commonChunk . addChunk ( asyncChunk ) ;
commonChunk = asyncChunk ;
}
2014-12-22 19:33:11 +08:00
usedChunks . forEach ( function ( chunk ) {
chunk . modules . forEach ( function ( module ) {
var idx = commonModules . indexOf ( module ) ;
if ( idx < 0 ) {
commonModules . push ( module ) ;
commonModulesCount . push ( 1 ) ;
} else {
commonModulesCount [ idx ] ++ ;
}
} ) ;
} ) ;
2015-01-12 06:15:11 +08:00
var reallyUsedChunks = [ ] ;
var reallyUsedModules = [ ] ;
2014-12-22 19:33:11 +08:00
commonModulesCount . forEach ( function ( count , idx ) {
2013-12-03 16:27:15 +08:00
var module = commonModules [ idx ] ;
2015-01-12 06:15:11 +08:00
if ( typeof minChunks === "function" ) {
if ( ! minChunks ( module , count ) )
2014-12-22 19:33:11 +08:00
return ;
2015-01-12 06:15:11 +08:00
} else if ( count < ( minChunks || Math . max ( 2 , usedChunks . length ) ) ) {
2014-12-22 19:33:11 +08:00
return ;
}
2015-01-12 06:15:11 +08:00
reallyUsedModules . push ( module ) ;
} ) ;
if ( minSize ) {
var size = reallyUsedModules . map ( function ( module ) {
return module . size ( ) ;
} ) . reduce ( function ( a , b ) { return a + b ; } , 0 ) ;
if ( size < minSize )
return ;
}
reallyUsedModules . forEach ( function ( module ) {
2013-12-03 18:34:38 +08:00
usedChunks . forEach ( function ( chunk ) {
2015-01-12 06:15:11 +08:00
if ( module . removeChunk ( chunk ) ) {
if ( reallyUsedChunks . indexOf ( chunk ) < 0 )
reallyUsedChunks . push ( chunk ) ;
}
2013-12-03 16:27:15 +08:00
} ) ;
commonChunk . addModule ( module ) ;
module . addChunk ( commonChunk ) ;
2014-12-22 19:33:11 +08:00
} ) ;
2015-01-12 06:15:11 +08:00
if ( async ) {
reallyUsedChunks . forEach ( function ( chunk ) {
if ( chunk . initial || chunk . entry )
return ;
chunk . blocks . forEach ( function ( block ) {
block . chunks . unshift ( commonChunk ) ;
commonChunk . addBlock ( block ) ;
} ) ;
} ) ;
asyncChunk . origins = reallyUsedChunks . map ( function ( chunk ) {
return chunk . origins . map ( function ( origin ) {
var newOrigin = Object . create ( origin ) ;
newOrigin . reasons = ( origin . reasons || [ ] ) . slice ( ) ;
newOrigin . reasons . push ( "async commons" ) ;
return newOrigin ;
} ) ;
} ) . reduce ( function ( arr , a ) { arr . push . apply ( arr , a ) ; return arr ; } , [ ] ) ;
} else {
usedChunks . forEach ( function ( chunk ) {
chunk . parents = [ commonChunk ] ;
commonChunk . chunks . push ( chunk ) ;
if ( chunk . initial )
commonChunk . initial = true ;
if ( chunk . entry ) {
commonChunk . entry = true ;
chunk . entry = false ;
}
} ) ;
}
2014-12-22 19:33:11 +08:00
if ( filenameTemplate )
commonChunk . filenameTemplate = filenameTemplate ;
2015-01-12 06:15:11 +08:00
} , this ) ;
2013-12-03 16:27:15 +08:00
} ) ;
} ) ;
2013-12-04 00:14:28 +08:00
} ;