@@ -263,6 +263,8 @@ class Compiler {
263263 this . _assetEmittingSourceCache = new WeakMap ( ) ;
264264 /** @private @type {Map<string, number> } */
265265 this . _assetEmittingWrittenFiles = new Map ( ) ;
266+ /** @private @type {Set<string> } */
267+ this . _assetEmittingPreviousFiles = new Set ( ) ;
266268 }
267269
268270 /**
@@ -556,6 +558,8 @@ class Compiler {
556558 compilation . assets = { ...compilation . assets } ;
557559 /** @type {Map<string, { path: string, source: Source, size: number, waiting: { cacheEntry: any, file: string }[] }> } */
558560 const caseInsensitiveMap = new Map ( ) ;
561+ /** @type {Set<string> } */
562+ const allTargetPaths = new Set ( ) ;
559563 asyncLib . forEachLimit (
560564 assets ,
561565 15 ,
@@ -583,6 +587,7 @@ class Compiler {
583587 outputPath ,
584588 targetFile
585589 ) ;
590+ allTargetPaths . add ( targetPath ) ;
586591
587592 // check if the target file has already been written by this Compiler
588593 const targetFileGeneration = this . _assetEmittingWrittenFiles . get (
@@ -775,18 +780,22 @@ ${other}`);
775780 // check if the Source has been written to this target file
776781 const writtenGeneration = cacheEntry . writtenTo . get ( targetPath ) ;
777782 if ( writtenGeneration === targetFileGeneration ) {
778- // if yes, we skip writing the file
779- // as it's already there
780- // (we assume one doesn't remove files while the Compiler is running)
783+ // if yes, we may skip writing the file
784+ // if it's already there
785+ // (we assume one doesn't modify files while the Compiler is running, other then removing them )
781786
782- compilation . updateAsset ( file , cacheEntry . sizeOnlySource , {
783- size : cacheEntry . sizeOnlySource . size ( )
784- } ) ;
785-
786- return callback ( ) ;
787- }
787+ if ( this . _assetEmittingPreviousFiles . has ( targetPath ) ) {
788+ // We assume that assets from the last compilation say intact on disk (they are not removed)
789+ compilation . updateAsset ( file , cacheEntry . sizeOnlySource , {
790+ size : cacheEntry . sizeOnlySource . size ( )
791+ } ) ;
788792
789- if ( ! immutable ) {
793+ return callback ( ) ;
794+ } else {
795+ // Settings immutable will make it accept file content without comparing when file exist
796+ immutable = true ;
797+ }
798+ } else if ( ! immutable ) {
790799 if ( checkSimilarFile ( ) ) return ;
791800 // We wrote to this file before which has very likely a different content
792801 // skip comparing and assume content is different for performance
@@ -822,7 +831,12 @@ ${other}`);
822831 err => {
823832 // Clear map to free up memory
824833 caseInsensitiveMap . clear ( ) ;
825- if ( err ) return callback ( err ) ;
834+ if ( err ) {
835+ this . _assetEmittingPreviousFiles . clear ( ) ;
836+ return callback ( err ) ;
837+ }
838+
839+ this . _assetEmittingPreviousFiles = allTargetPaths ;
826840
827841 this . hooks . afterEmit . callAsync ( compilation , err => {
828842 if ( err ) return callback ( err ) ;
0 commit comments