|
@ -39,7 +39,6 @@ export default class Bundle { |
|
|
.map( plugin => plugin.transform ) |
|
|
.map( plugin => plugin.transform ) |
|
|
.filter( Boolean ); |
|
|
.filter( Boolean ); |
|
|
|
|
|
|
|
|
this.pending = blank(); |
|
|
|
|
|
this.moduleById = blank(); |
|
|
this.moduleById = blank(); |
|
|
this.modules = []; |
|
|
this.modules = []; |
|
|
|
|
|
|
|
@ -57,15 +56,23 @@ export default class Bundle { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
build () { |
|
|
build () { |
|
|
|
|
|
// Phase 1 – discovery. We load the entry module and find which
|
|
|
|
|
|
// modules it imports, and import those, until we have all
|
|
|
|
|
|
// of the entry module's dependencies
|
|
|
return Promise.resolve( this.resolveId( this.entry, undefined ) ) |
|
|
return Promise.resolve( this.resolveId( this.entry, undefined ) ) |
|
|
.then( id => this.fetchModule( id, undefined ) ) |
|
|
.then( id => this.fetchModule( id, undefined ) ) |
|
|
.then( entryModule => { |
|
|
.then( entryModule => { |
|
|
this.entryModule = entryModule; |
|
|
this.entryModule = entryModule; |
|
|
|
|
|
|
|
|
|
|
|
// Phase 2 – binding. We link references to their declarations
|
|
|
|
|
|
// to generate a complete picture of the bundle
|
|
|
this.modules.forEach( module => module.bindImportSpecifiers() ); |
|
|
this.modules.forEach( module => module.bindImportSpecifiers() ); |
|
|
this.modules.forEach( module => module.bindAliases() ); |
|
|
this.modules.forEach( module => module.bindAliases() ); |
|
|
this.modules.forEach( module => module.bindReferences() ); |
|
|
this.modules.forEach( module => module.bindReferences() ); |
|
|
|
|
|
|
|
|
|
|
|
// Phase 3 – marking. We 'run' each statement to see which ones
|
|
|
|
|
|
// need to be included in the generated bundle
|
|
|
|
|
|
|
|
|
// mark all export statements
|
|
|
// mark all export statements
|
|
|
entryModule.getExports().forEach( name => { |
|
|
entryModule.getExports().forEach( name => { |
|
|
const declaration = entryModule.traceExport( name ); |
|
|
const declaration = entryModule.traceExport( name ); |
|
@ -80,16 +87,17 @@ export default class Bundle { |
|
|
settled = true; |
|
|
settled = true; |
|
|
|
|
|
|
|
|
if ( this.aggressive ) { |
|
|
if ( this.aggressive ) { |
|
|
settled = !entryModule.markStatements(); |
|
|
settled = !entryModule.run(); |
|
|
} else { |
|
|
} else { |
|
|
this.modules.forEach( module => { |
|
|
this.modules.forEach( module => { |
|
|
if ( module.markStatements() ) { |
|
|
if ( module.run() ) settled = false; |
|
|
settled = false; |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
this.orderedModules = this.sort(); |
|
|
this.orderedModules = this.sort(); |
|
|
this.deconflict(); |
|
|
this.deconflict(); |
|
|
}); |
|
|
}); |
|
@ -129,8 +137,8 @@ export default class Bundle { |
|
|
|
|
|
|
|
|
fetchModule ( id, importer ) { |
|
|
fetchModule ( id, importer ) { |
|
|
// short-circuit cycles
|
|
|
// short-circuit cycles
|
|
|
if ( this.pending[ id ] ) return null; |
|
|
if ( id in this.moduleById ) return null; |
|
|
this.pending[ id ] = true; |
|
|
this.moduleById[ id ] = null; |
|
|
|
|
|
|
|
|
return Promise.resolve( this.load( id ) ) |
|
|
return Promise.resolve( this.load( id ) ) |
|
|
.catch( err => { |
|
|
.catch( err => { |
|
|