diff --git a/src/Bundle.js b/src/Bundle.js index babb887..4636a6c 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -121,12 +121,14 @@ export default class Bundle { this.entryModule = entryModule; // Phase 2 – binding. We link references to their declarations - // to generate a complete picture of the bundle + // to generate a complete picture of the bundle, then sort + // modules according to the order of their import declarations timeStart( 'phase 2' ); this.modules.forEach( module => module.bindImportSpecifiers() ); this.modules.forEach( module => module.bindReferences() ); + this.orderedModules = this.sort(); timeEnd( 'phase 2' ); @@ -177,13 +179,10 @@ export default class Bundle { timeEnd( 'phase 3' ); - // Phase 4 – final preparation. We order the modules with an - // enhanced topological sort that accounts for cycles, then - // ensure that names are deconflicted throughout the bundle - + // Phase 4 – check for unused external imports, then deconflict + // names throughout the bundle timeStart( 'phase 4' ); - // while we're here, check for unused external imports this.externalModules.forEach( module => { const unused = Object.keys( module.declarations ) .filter( name => name !== '*' ) @@ -201,7 +200,6 @@ export default class Bundle { }); }); - this.orderedModules = this.sort(); this.deconflict(); timeEnd( 'phase 4' ); @@ -534,43 +532,11 @@ export default class Bundle { } sort () { - let hasCycles; const seen = {}; const ordered = []; - const stronglyDependsOn = blank(); - const dependsOn = blank(); - - this.modules.forEach( module => { - stronglyDependsOn[ module.id ] = blank(); - dependsOn[ module.id ] = blank(); - }); - - this.modules.forEach( module => { - function processStrongDependency ( dependency ) { - if ( dependency === module || stronglyDependsOn[ module.id ][ dependency.id ] ) return; - - stronglyDependsOn[ module.id ][ dependency.id ] = true; - dependency.strongDependencies.forEach( processStrongDependency ); - } - - function processDependency ( dependency ) { - if ( dependency === module || dependsOn[ module.id ][ dependency.id ] ) return; - - dependsOn[ module.id ][ dependency.id ] = true; - dependency.dependencies.forEach( processDependency ); - } - - module.strongDependencies.forEach( processStrongDependency ); - module.dependencies.forEach( processDependency ); - }); - const visit = module => { - if ( seen[ module.id ] ) { - hasCycles = true; - return; - } - + if ( seen[ module.id ] ) return; seen[ module.id ] = true; module.dependencies.forEach( visit ); @@ -578,42 +544,6 @@ export default class Bundle { }; visit( this.entryModule ); - - if ( hasCycles ) { - ordered.forEach( ( a, i ) => { - for ( i += 1; i < ordered.length; i += 1 ) { - const b = ordered[i]; - - // TODO reinstate this! it no longer works - if ( stronglyDependsOn[ a.id ][ b.id ] ) { - // somewhere, there is a module that imports b before a. Because - // b imports a, a is placed before b. We need to find the module - // in question, so we can provide a useful error message - let parent = '[[unknown]]'; - const visited = {}; - - const findParent = module => { - if ( dependsOn[ module.id ][ a.id ] && dependsOn[ module.id ][ b.id ] ) { - parent = module.id; - return true; - } - visited[ module.id ] = true; - for ( let i = 0; i < module.dependencies.length; i += 1 ) { - const dependency = module.dependencies[i]; - if ( !visited[ dependency.id ] && findParent( dependency ) ) return true; - } - }; - - findParent( this.entryModule ); - - this.onwarn( - `Module ${a.id} may be unable to evaluate without ${b.id}, but is included first due to a cyclical dependency. Consider swapping the import statements in ${parent} to ensure correct ordering` - ); - } - } - }); - } - return ordered; }