@@ -23,13 +23,26 @@ const objectAssign = require('object-assign');
2323
2424const flatten = arr => arr . reduce ( ( prev , curr ) => prev . concat ( curr ) , [ ] ) ;
2525
26- const isChunkBelongToHtml = ( chunk , roots ) => {
26+ const doesChunkBelongToHTML = ( chunk , roots , visitedChunks ) => {
27+ // Prevent circular recursion.
28+ // See https://github.com/GoogleChromeLabs/preload-webpack-plugin/issues/49
29+ if ( visitedChunks [ chunk . renderedHash ] ) {
30+ return false ;
31+ }
32+ visitedChunks [ chunk . renderedHash ] = true ;
33+
2734 for ( const root of roots ) {
28- if ( root . hash === chunk . renderedHash ) return true ;
35+ if ( root . hash === chunk . renderedHash ) {
36+ return true ;
37+ }
2938 }
39+
3040 for ( const parent of chunk . parents ) {
31- if ( isChunkBelongToHtml ( parent , roots ) ) return true ;
41+ if ( doesChunkBelongToHTML ( parent , roots , visitedChunks ) ) {
42+ return true ;
43+ }
3244 }
45+
3346 return false ;
3447} ;
3548
@@ -80,7 +93,8 @@ class PreloadPlugin {
8093 const publicPath = compilation . outputOptions . publicPath || '' ;
8194
8295 // Only handle the chunk import by the htmlWebpackPlugin
83- extractedChunks = extractedChunks . filter ( chunk => isChunkBelongToHtml ( chunk , Object . values ( htmlPluginData . assets . chunks ) ) ) ;
96+ extractedChunks = extractedChunks . filter ( chunk => doesChunkBelongToHTML (
97+ chunk , Object . values ( htmlPluginData . assets . chunks ) , { } ) ) ;
8498
8599 flatten ( extractedChunks . map ( chunk => chunk . files ) ) . filter ( entry => {
86100 return this . options . fileBlacklist . every ( regex => regex . test ( entry ) === false ) ;
0 commit comments