@@ -46,9 +46,9 @@ Compilation.prototype = Object.create(Tapable.prototype);
4646Compilation . prototype . addModule = function ( module ) {
4747 var identifier = module . identifier ( ) ;
4848 if ( this . _modules [ identifier ] ) return false ;
49- if ( this . cache && this . cache [ identifier ] ) {
50- var cacheModule = this . cache [ identifier ] ;
51-
49+ if ( this . cache && this . cache [ "m" + identifier ] ) {
50+ var cacheModule = this . cache [ "m" + identifier ] ;
51+
5252 var rebuild = true ;
5353 if ( ! cacheModule . error && cacheModule . cacheable && this . fileTimestamps && this . contextTimestamps ) {
5454 rebuild = cacheModule . needRebuild ( this . fileTimestamps , this . contextTimestamps ) ;
@@ -65,10 +65,12 @@ Compilation.prototype.addModule = function(module) {
6565 this . warnings . push ( err ) ;
6666 } , this ) ;
6767 return cacheModule ;
68+ } else {
69+ module . lastId = cacheModule . id ;
6870 }
6971 }
7072 this . _modules [ identifier ] = module ;
71- if ( this . cache ) this . cache [ identifier ] = module ;
73+ if ( this . cache ) this . cache [ "m" + identifier ] = module ;
7274 this . modules . push ( module ) ;
7375 return true ;
7476} ;
@@ -164,7 +166,7 @@ Compilation.prototype.processModuleDependencies = function(module, callback) {
164166 }
165167 if ( err ) return errorOrWarningAndCallback ( new ModuleNotFoundError ( module , err ) ) ;
166168 if ( ! dependantModule ) return callback ( ) ;
167-
169+
168170 var newModule = this . addModule ( dependantModule ) ;
169171
170172 if ( ! newModule ) {
@@ -180,15 +182,15 @@ Compilation.prototype.processModuleDependencies = function(module, callback) {
180182
181183 if ( newModule instanceof Module ) { // from cache
182184 dependantModule = newModule ;
183-
185+
184186 dependencies . forEach ( function ( dep ) {
185187 dep . module = dependantModule ;
186188 dependantModule . addReason ( module , dep ) ;
187189 } ) ;
188190
189191 return this . processModuleDependencies ( dependantModule , callback ) ;
190192 }
191-
193+
192194 this . buildModule ( dependantModule , function ( err ) {
193195 if ( err ) return errorOrWarningAndCallback ( err ) ;
194196
@@ -231,7 +233,7 @@ Compilation.prototype.addEntry = function process(context, entry, name, callback
231233 if ( ! result ) {
232234 return callback ( new Error ( "Entry module is already added" ) ) ;
233235 }
234-
236+
235237 if ( result instanceof Module ) {
236238 module = result ;
237239 }
@@ -248,7 +250,7 @@ Compilation.prototype.addEntry = function process(context, entry, name, callback
248250 entryReady . call ( this ) ;
249251 } . bind ( this ) ) ;
250252 }
251-
253+
252254 function entryReady ( ) {
253255 this . processModuleDependencies ( module , function ( err ) {
254256 if ( err ) return callback ( err ) ;
@@ -272,7 +274,9 @@ Compilation.prototype.seal = function seal(callback) {
272274 this . applyPlugins ( "after-optimize-modules" , this . modules ) ;
273275 this . applyPlugins ( "optimize-chunks" , this . chunks ) ;
274276 this . applyPlugins ( "after-optimize-chunks" , this . chunks ) ;
277+ this . applyPlugins ( "optimize-module-order" , this . modules ) ;
275278 this . applyModuleIds ( ) ;
279+ this . applyPlugins ( "optimize-chunk-order" , this . chunks ) ;
276280 this . applyChunkIds ( ) ;
277281 this . applyPlugins ( "optimize-module-ids" , this . modules ) ;
278282 this . applyPlugins ( "after-optimize-module-ids" , this . modules ) ;
@@ -337,77 +341,25 @@ Compilation.prototype.processDependenciesBlockForChunk = function processDepende
337341} ;
338342
339343Compilation . prototype . applyModuleIds = function applyModuleIds ( ) {
340- var i = 0 ;
341- function entryChunks ( m ) {
342- return m . chunks . filter ( function ( c ) {
343- return c . entry ;
344- } ) . length ;
345- }
346- function occursInEntry ( m ) {
347- return m . reasons . map ( function ( r ) {
348- if ( ! r . module ) return 0 ;
349- return entryChunks ( r . module ) ;
350- } ) . reduce ( function ( a , b ) { return a + b ; } , 0 ) + entryChunks ( m ) ;
351- }
352- function occurs ( m ) {
353- return m . reasons . map ( function ( r ) {
354- if ( ! r . module ) return 0 ;
355- return r . module . chunks . length ;
356- } ) . reduce ( function ( a , b ) { return a + b ; } , 0 ) + m . chunks . length ;
357- }
358- this . modules . sort ( function ( a , b ) {
359- var aEntryOccurs = occursInEntry ( a ) ;
360- var bEntryOccurs = occursInEntry ( b ) ;
361- if ( aEntryOccurs > bEntryOccurs ) return - 1 ;
362- if ( aEntryOccurs < bEntryOccurs ) return 1 ;
363- var aOccurs = occurs ( a ) ;
364- var bOccurs = occurs ( b ) ;
365- if ( aOccurs > bOccurs ) return - 1 ;
366- if ( aOccurs < bOccurs ) return 1 ;
367- if ( a . identifier ( ) > b . identifier ( ) ) return 1 ;
368- if ( a . identifier ( ) < b . identifier ( ) ) return - 1 ;
369- return 0 ;
370- } ) ;
344+ var i = this . cache && this . cache [ "nextModuleId" ] || 1 ;
345+ var usedIds = { 0 :true } ;
371346 this . modules . forEach ( function ( module ) {
372- if ( module . id === null )
373- module . id = ++ i ;
347+ if ( module . id === null ) {
348+ if ( module . lastId > 0 ) {
349+ if ( ! usedIds [ module . lastId ] ) {
350+ usedIds [ module . lastId ] = true ;
351+ module . id = module . lastId ;
352+ return ;
353+ }
354+ }
355+ module . id = i ++ ;
356+ }
374357 } ) ;
358+ if ( this . cache ) this . cache [ "nextModuleId" ] = i ;
375359} ;
376360
377361Compilation . prototype . applyChunkIds = function applyChunkIds ( ) {
378362 var i = 0 ;
379- function occursInEntry ( c ) {
380- return c . parents . filter ( function ( p ) {
381- return p . entry ;
382- } ) . length ;
383- }
384- function occurs ( c ) {
385- return c . blocks . length ;
386- }
387- this . chunks . forEach ( function ( c ) {
388- c . modules . sort ( function ( a , b ) {
389- if ( a . identifier ( ) > b . identifier ( ) ) return 1 ;
390- if ( a . identifier ( ) < b . identifier ( ) ) return - 1 ;
391- return 0 ;
392- } ) ;
393- } ) ;
394- this . chunks . sort ( function ( a , b ) {
395- var aEntryOccurs = occursInEntry ( a ) ;
396- var bEntryOccurs = occursInEntry ( b ) ;
397- if ( aEntryOccurs > bEntryOccurs ) return - 1 ;
398- if ( aEntryOccurs < bEntryOccurs ) return 1 ;
399- var aOccurs = occurs ( a ) ;
400- var bOccurs = occurs ( b ) ;
401- if ( aOccurs > bOccurs ) return - 1 ;
402- if ( aOccurs < bOccurs ) return 1 ;
403- if ( a . modules . length > b . modules . length ) return - 1 ;
404- if ( a . modules . length < b . modules . length ) return 1 ;
405- for ( var i = 0 ; i < a . modules . length ; i ++ ) {
406- if ( a . modules [ i ] . identifier ( ) > b . modules [ i ] . identifier ( ) ) return - 1 ;
407- if ( a . modules [ i ] . identifier ( ) < b . modules [ i ] . identifier ( ) ) return 1 ;
408- }
409- return 0 ;
410- } ) ;
411363 this . chunks . forEach ( function ( chunk ) {
412364 if ( chunk . id === null )
413365 chunk . id = ++ i ;
@@ -494,7 +446,17 @@ Compilation.prototype.createChunkAssets = function createChunkAssets() {
494446 var source ;
495447 var file ;
496448 if ( chunk . entry ) {
497- source = this . mainTemplate . render ( hash , chunk , this . moduleTemplate , this . dependencyTemplates ) ;
449+ if ( this . cache && this . cache [ "c" + chunk . id + chunk . name ] && this . cache [ "c" + chunk . id + chunk . name ] . hash == hash ) {
450+ source = this . cache [ "c" + chunk . id + chunk . name ] . source ;
451+ } else {
452+ source = this . mainTemplate . render ( hash , chunk , this . moduleTemplate , this . dependencyTemplates ) ;
453+ if ( this . cache ) {
454+ this . cache [ "c" + chunk . id + chunk . name ] = {
455+ hash : hash ,
456+ source : source
457+ }
458+ }
459+ }
498460 this . assets [
499461 file = filename
500462 . replace ( Template . REGEXP_HASH , hash )
@@ -504,7 +466,23 @@ Compilation.prototype.createChunkAssets = function createChunkAssets() {
504466 chunk . files . push ( file ) ;
505467 this . applyPlugins ( "chunk-asset" , chunk , file ) ;
506468 } else {
507- source = this . chunkTemplate . render ( chunk , this . moduleTemplate , this . dependencyTemplates ) ;
469+ if ( this . cache ) {
470+ var chunkHash = new ( require ( "crypto" ) . Hash ) ( "md5" ) ;
471+ chunk . updateHash ( chunkHash ) ;
472+ this . chunkTemplate . updateHash ( chunkHash ) ;
473+ chunkHash = chunkHash . digest ( "hex" ) ;
474+ }
475+ if ( this . cache && this . cache [ "c" + chunk . id ] && this . cache [ "c" + chunk . id ] . hash == chunkHash ) {
476+ source = this . cache [ "c" + chunk . id ] . source ;
477+ } else {
478+ source = this . chunkTemplate . render ( chunk , this . moduleTemplate , this . dependencyTemplates ) ;
479+ if ( this . cache ) {
480+ this . cache [ "c" + chunk . id ] = {
481+ hash : chunkHash ,
482+ source : source
483+ }
484+ }
485+ }
508486 this . assets [
509487 file = chunkFilename
510488 . replace ( Template . REGEXP_HASH , hash )
0 commit comments