2013-12-03 16:27:15 +08:00
/ *
MIT License http : //www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @ sokra
* /
2015-11-21 04:29:32 +08:00
var nextIdent = 0 ;
2015-10-29 06:26:52 +08:00
function CommonsChunkPlugin ( options ) {
2016-01-22 12:01:00 +08:00
if ( arguments . length > 1 ) {
throw new Error ( "Deprecation notice: CommonsChunkPlugin now only takes a single argument. Either an options " +
2016-06-16 06:52:50 +08:00
"object *or* the name of the chunk.\n" +
"Example: if your old code looked like this:\n" +
" new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js')\n\n" +
"You would change it to:\n" +
" new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.bundle.js' })\n\n" +
"The available options are:\n" +
" name: string\n" +
" names: string[]\n" +
" filename: string\n" +
" minChunks: number\n" +
2016-12-06 18:55:48 +08:00
" chunks: string[]\n" +
" children: boolean\n" +
2016-06-16 06:52:50 +08:00
" async: boolean\n" +
" minSize: number\n" ) ;
2016-01-22 12:01:00 +08:00
}
2015-10-29 06:26:52 +08:00
if ( Array . isArray ( options ) || typeof options === "string" ) {
2015-10-31 22:31:10 +08:00
options = {
name : options
} ;
2014-07-19 20:32:48 +08:00
}
2015-10-29 06:26:52 +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 ;
2016-12-07 08:43:17 +08:00
this . async = options . async ;
2015-10-29 06:26:52 +08:00
this . minSize = options . minSize ;
2015-11-21 04:29:32 +08:00
this . ident = _ _filename + ( nextIdent ++ ) ;
2013-12-03 16:27:15 +08:00
}
2015-11-21 04:29:32 +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 ;
2016-12-07 08:43:17 +08:00
var asyncOption = this . async ;
2015-01-12 06:15:11 +08:00
var minSize = this . minSize ;
2015-11-21 04:29:32 +08:00
var ident = this . ident ;
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-11-21 04:29:32 +08:00
// only optimize once
if ( compilation [ ident ] ) return ;
compilation [ ident ] = true ;
2015-04-27 04:47:47 +08:00
var commonChunks ;
2016-12-07 07:40:49 +08:00
if ( ! chunkNames && ( selectedChunks === false || asyncOption ) ) {
2015-04-27 04:47:47 +08:00
commonChunks = chunks ;
2015-11-21 03:23:42 +08:00
} else if ( Array . isArray ( chunkNames ) || typeof chunkNames === "string" ) {
commonChunks = [ ] . concat ( chunkNames ) . map ( function ( chunkName ) {
var chunk = chunks . filter ( function ( chunk ) {
2015-04-29 18:46:00 +08:00
return chunk . name === chunkName ;
} ) [ 0 ] ;
2015-11-21 03:23:42 +08:00
if ( ! chunk ) {
chunk = this . addChunk ( chunkName ) ;
}
return chunk ;
} , this ) ;
2014-12-22 19:33:11 +08:00
} else {
2015-11-21 03:23:42 +08:00
throw new Error ( "Invalid chunkNames argument" ) ;
2014-12-22 19:33:11 +08:00
}
2015-04-27 04:47:47 +08:00
commonChunks . forEach ( function processCommonChunk ( commonChunk , idx ) {
var usedChunks ;
2015-07-16 06:19:23 +08:00
if ( Array . isArray ( selectedChunks ) ) {
2015-04-27 04:47:47 +08:00
usedChunks = chunks . filter ( function ( chunk ) {
2015-07-16 06:19:23 +08:00
if ( chunk === commonChunk ) return false ;
2014-12-22 19:33:11 +08:00
return selectedChunks . indexOf ( chunk . name ) >= 0 ;
} ) ;
2016-12-07 07:40:49 +08:00
} else if ( selectedChunks === false || asyncOption ) {
2015-04-27 04:47:47 +08:00
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
2016-12-07 07:40:49 +08:00
return asyncOption || chunk . parents . length === 1 ;
2014-12-22 19:33:11 +08:00
} ) ;
} else {
2016-07-13 17:03:14 +08:00
if ( commonChunk . parents . length > 0 ) {
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 ) ;
2015-07-16 06:19:23 +08:00
if ( found >= idx ) return false ;
2016-07-13 17:03:14 +08:00
return chunk . hasRuntime ( ) ;
2014-12-22 19:33:11 +08:00
} ) ;
}
2016-12-07 07:40:49 +08:00
if ( asyncOption ) {
var asyncChunk = this . addChunk ( typeof asyncOption === "string" ? asyncOption : undefined ) ;
2015-01-12 06:15:11 +08:00
asyncChunk . chunkReason = "async commons chunk" ;
asyncChunk . extraAsync = true ;
asyncChunk . addParent ( commonChunk ) ;
commonChunk . addChunk ( asyncChunk ) ;
commonChunk = asyncChunk ;
}
var reallyUsedModules = [ ] ;
2016-06-16 06:52:50 +08:00
if ( minChunks !== Infinity ) {
2016-04-07 01:51:09 +08:00
var commonModulesCount = [ ] ;
var commonModules = [ ] ;
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 ] ++ ;
}
} ) ;
} ) ;
2017-01-11 17:51:58 +08:00
var _minChunks = ( minChunks || Math . max ( 2 , usedChunks . length ) ) ;
2016-04-07 01:51:09 +08:00
commonModulesCount . forEach ( function ( count , idx ) {
var module = commonModules [ idx ] ;
if ( typeof minChunks === "function" ) {
if ( ! minChunks ( module , count ) )
return ;
} else if ( count < _minChunks ) {
2014-12-22 19:33:11 +08:00
return ;
2016-04-07 01:51:09 +08:00
}
2016-11-10 15:52:00 +08:00
if ( module . chunkCondition && ! module . chunkCondition ( commonChunk ) )
return ;
2016-04-07 01:51:09 +08:00
reallyUsedModules . push ( module ) ;
} ) ;
}
2015-07-16 06:19:23 +08:00
if ( minSize ) {
2015-05-22 03:39:08 +08:00
var size = reallyUsedModules . reduce ( function ( a , b ) {
return a + b . size ( ) ;
} , 0 ) ;
2015-07-16 06:19:23 +08:00
if ( size < minSize )
2015-01-12 06:15:11 +08:00
return ;
}
2016-04-07 01:51:09 +08:00
var reallyUsedChunks = [ ] ;
2015-01-12 06:15:11 +08:00
reallyUsedModules . forEach ( function ( module ) {
2013-12-03 18:34:38 +08:00
usedChunks . forEach ( function ( chunk ) {
2015-07-16 06:19:23 +08:00
if ( module . removeChunk ( chunk ) ) {
if ( reallyUsedChunks . indexOf ( chunk ) < 0 )
2015-01-12 06:15:11 +08:00
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
} ) ;
2016-12-07 07:40:49 +08:00
if ( asyncOption ) {
2015-01-12 06:15:11 +08:00
reallyUsedChunks . forEach ( function ( chunk ) {
2016-07-13 17:03:14 +08:00
if ( chunk . isInitial ( ) )
2015-01-12 06:15:11 +08:00
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 ;
} ) ;
2015-07-13 06:20:09 +08:00
} ) . reduce ( function ( arr , a ) {
arr . push . apply ( arr , a ) ;
return arr ;
} , [ ] ) ;
2015-01-12 06:15:11 +08:00
} else {
usedChunks . forEach ( function ( chunk ) {
chunk . parents = [ commonChunk ] ;
2016-07-13 17:03:14 +08:00
chunk . entrypoints . forEach ( function ( ep ) {
ep . insertChunk ( commonChunk , chunk ) ;
} ) ;
2016-07-16 03:59:24 +08:00
commonChunk . addChunk ( chunk ) ;
2015-01-12 06:15:11 +08:00
} ) ;
}
2015-07-16 06:19:23 +08:00
if ( filenameTemplate )
2014-12-22 19:33:11 +08:00
commonChunk . filenameTemplate = filenameTemplate ;
2015-01-12 06:15:11 +08:00
} , this ) ;
2015-11-21 04:35:37 +08:00
return true ;
2013-12-03 16:27:15 +08:00
} ) ;
} ) ;
2013-12-04 00:14:28 +08:00
} ;