@@ -34,14 +34,19 @@ class HtmlWebpackChildCompiler {
3434 */
3535 this . compilationPromise ;
3636 /**
37- * @type {Date }
37+ * @type {number }
3838 */
39- this . compilationStarted ;
39+ this . compilationStartedTimestamp ;
4040 /**
4141 * All file dependencies of the child compiler
4242 * @type {string[] }
4343 */
4444 this . fileDependencies = [ ] ;
45+ /**
46+ * Store if the cache was already verified for the given compilation
47+ * @type {WeakMap<WebpackCompilation, boolean> }}
48+ */
49+ this . cacheVerifiedForCompilation = new WeakMap ( ) ;
4550 }
4651
4752 /**
@@ -63,6 +68,7 @@ class HtmlWebpackChildCompiler {
6368 // Add the template to the childCompiler
6469 const newTemplateId = this . templates . length ;
6570 this . templates . push ( template ) ;
71+ // Mark the cache invalid
6672 return newTemplateId ;
6773 }
6874
@@ -117,7 +123,7 @@ class HtmlWebpackChildCompiler {
117123 new SingleEntryPlugin ( childCompiler . context , template , `HtmlWebpackPlugin_${ index } ` ) . apply ( childCompiler ) ;
118124 } ) ;
119125
120- this . compilationStarted = new Date ( ) ;
126+ this . compilationStartedTimestamp = new Date ( ) . getTime ( ) ;
121127 this . compilationPromise = new Promise ( ( resolve , reject ) => {
122128 childCompiler . runAsChild ( ( err , entries , childCompilation ) => {
123129 // Extract templates
@@ -159,6 +165,37 @@ class HtmlWebpackChildCompiler {
159165
160166 return this . compilationPromise ;
161167 }
168+
169+ /**
170+ * Returns `false` if any template file depenendencies has changed
171+ * for the given main compilation
172+ *
173+ * @param {WebpackCompilation } mainCompilation
174+ * @returns {boolean }
175+ */
176+ hasOutDatedTemplateCache ( mainCompilation ) {
177+ // Check if cache validation was already computed
178+ const isCacheValid = this . cacheVerifiedForCompilation . get ( mainCompilation ) ;
179+ if ( isCacheValid !== undefined ) {
180+ return isCacheValid ;
181+ }
182+ // If the compilation was never run there is no invalid cache
183+ if ( ! this . compilationStartedTimestamp ) {
184+ this . cacheVerifiedForCompilation . set ( mainCompilation , false ) ;
185+ return false ;
186+ }
187+ // Check if any dependent file was changed after the last compilation
188+ const fileTimestamps = mainCompilation . fileTimestamps ;
189+ const isCacheOutOfDate = this . fileDependencies . some ( ( fileDependency ) => {
190+ const timestamp = fileTimestamps . get ( fileDependency ) ;
191+ // If the timestamp is not known the file is new
192+ // If the timestamp is larger then the file has changed
193+ // Otherwise the file is still the same
194+ return ! timestamp || timestamp > this . compilationStartedTimestamp ;
195+ } ) ;
196+ this . cacheVerifiedForCompilation . set ( mainCompilation , isCacheOutOfDate ) ;
197+ return isCacheOutOfDate ;
198+ }
162199}
163200
164201/**
@@ -215,10 +252,13 @@ const childCompilerCache = new WeakMap();
215252 * @param {WebpackCompiler } mainCompiler
216253 */
217254function getChildCompiler ( mainCompiler ) {
218- if ( ! childCompilerCache [ mainCompiler ] ) {
219- childCompilerCache [ mainCompiler ] = new HtmlWebpackChildCompiler ( ) ;
255+ const cachedChildCompiler = childCompilerCache . get ( mainCompiler ) ;
256+ if ( cachedChildCompiler ) {
257+ return cachedChildCompiler ;
220258 }
221- return childCompilerCache [ mainCompiler ] ;
259+ const newCompiler = new HtmlWebpackChildCompiler ( ) ;
260+ childCompilerCache . set ( mainCompiler , newCompiler ) ;
261+ return newCompiler ;
222262}
223263
224264/**
@@ -227,7 +267,7 @@ function getChildCompiler (mainCompiler) {
227267 * @param {WebpackCompiler } mainCompiler
228268 */
229269function clearCache ( mainCompiler ) {
230- delete ( childCompilerCache [ mainCompiler ] ) ;
270+ childCompilerCache . delete ( mainCompiler ) ;
231271}
232272
233273/**
@@ -253,6 +293,7 @@ function addTemplateToCompiler (mainCompiler, templatePath) {
253293function compileTemplate ( templatePath , outputFilename , mainCompilation ) {
254294 const childCompiler = getChildCompiler ( mainCompilation . compiler ) ;
255295 return childCompiler . compileTemplates ( mainCompilation ) . then ( ( compiledTemplates ) => {
296+ if ( ! compiledTemplates [ templatePath ] ) console . log ( Object . keys ( compiledTemplates ) , templatePath ) ;
256297 const compiledTemplate = compiledTemplates [ templatePath ] ;
257298 // Replace [hash] placeholders in filename
258299 const outputName = mainCompilation . mainTemplate . hooks . assetPath . call ( outputFilename , {
@@ -270,8 +311,20 @@ function compileTemplate (templatePath, outputFilename, mainCompilation) {
270311 } ) ;
271312}
272313
314+ /**
315+ * Returns false if the cache is not valid anymore
316+ *
317+ * @param {WebpackCompilation } compilation
318+ * @returns {boolean }
319+ */
320+ function hasOutDatedTemplateCache ( compilation ) {
321+ const childCompiler = childCompilerCache . get ( compilation . compiler ) ;
322+ return childCompiler ? childCompiler . hasOutDatedTemplateCache ( compilation ) : false ;
323+ }
324+
273325module . exports = {
274326 addTemplateToCompiler,
275327 compileTemplate,
328+ hasOutDatedTemplateCache,
276329 clearCache
277330} ;
0 commit comments