diff --git a/src/Bundle.js b/src/Bundle.js index 3ab7977..4b2dc03 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -155,6 +155,12 @@ export default class Bundle { // Determine export mode - 'default', 'named', 'none' const exportMode = getExportMode( this, options.exports ); + // Assign names to external modules + this.externalModules.forEach( module => { + const override = module.declarations['*'] || module.declarations.default; + if ( override ) module.name = override.name; + }); + let magicString = new MagicString.Bundle({ separator: '\n\n' }); this.orderedModules.forEach( module => { diff --git a/src/ExternalModule.js b/src/ExternalModule.js index c981c5e..57d01d8 100644 --- a/src/ExternalModule.js +++ b/src/ExternalModule.js @@ -4,11 +4,32 @@ import makeLegalIdentifier from './utils/makeLegalIdentifier'; class ExternalDeclaration { constructor ( module, name ) { this.module = module; - this.name = name; + this.importedAs = name; + + this.name = null; this.isExternal = true; this.references = []; } + + addReference ( reference ) { + reference.declaration = this; + this.name = reference.name; + } + + getName () { + if ( this.importedAs === '*' ) { + return this.module.name; + } + + if ( this.importedAs === 'default' ) { + return this.module.needsNamed ? + `${this.module.name}__default` : + this.module.name; + } + + return `${this.module.name}.${this.name}`; + } } export default class ExternalModule { @@ -19,8 +40,6 @@ export default class ExternalModule { this.isExternal = true; this.declarations = blank(); - this.suggestedNames = blank(); - this.needsDefault = false; // Invariant: needsNamed and needsAll are never both true at once. @@ -32,23 +51,12 @@ export default class ExternalModule { this.needsAll = false; } - findDefiningStatement () { - return null; - } - - rename () { - // noop - } - - suggestName ( exportName, suggestion ) { - if ( !this.suggestedNames[ exportName ] ) { - this.suggestedNames[ exportName ] = suggestion; - } - } - traceExport ( name ) { + // TODO is this necessary? where is it used? if ( name === 'default' ) { this.needsDefault = true; + } else if ( name === '*' ) { + this.needsAll = true; } else { this.needsNamed = true; } diff --git a/src/Module.js b/src/Module.js index 372029d..905181f 100644 --- a/src/Module.js +++ b/src/Module.js @@ -215,7 +215,7 @@ export default class Module { if ( declaration ) { reference.declaration = declaration; - declaration.references.push( reference ); + declaration.addReference( reference ); } else { // TODO handle globals this.bundle.assumedGlobals[ reference.name ] = true; @@ -523,7 +523,7 @@ export default class Module { if ( reference.declaration ) { const { start } = reference.node; const name = ( !es6 && declaration.isExternal ) ? - `${declaration.module.name}.${declaration.name}` : + declaration.getName() : declaration.name; magicString.overwrite( start, start + reference.name.length, name ); diff --git a/src/ast/Scope.js b/src/ast/Scope.js index c5ef05c..ed3419a 100644 --- a/src/ast/Scope.js +++ b/src/ast/Scope.js @@ -34,10 +34,15 @@ function extractNames ( param ) { } class Declaration { - constructor ( name ) { + constructor () { this.references = []; this.statement = null; - this.name = name; + this.name = null; + } + + addReference ( reference ) { + reference.declaration = this; + this.name = reference.name; // TODO handle differences of opinion } } diff --git a/src/finalisers/es6.js b/src/finalisers/es6.js index e21e066..f0031e8 100644 --- a/src/finalisers/es6.js +++ b/src/finalisers/es6.js @@ -18,20 +18,19 @@ export default function es6 ( bundle, magicString ) { const importBlock = bundle.externalModules .map( module => { const specifiers = []; + const importedNames = keys( module.declarations ) + .filter( name => name !== '*' && name !== 'default' ); - if ( module.needsDefault ) { - specifiers.push( module.importedByBundle.filter( declaration => - declaration.name === 'default' )[0].localName ); + if ( module.declarations.default ) { + specifiers.push( module.name ); } - if ( module.needsAll ) { - specifiers.push( '* as ' + module.importedByBundle.filter( declaration => - declaration.name === '*' )[0].localName ); + if ( module.declarations['*'] ) { + specifiers.push( `* as ${module.name}` ); } - if ( module.needsNamed ) { - specifiers.push( '{ ' + keys( module.declarations ) - .join( ', ' ) + ' }' ); + if ( importedNames.length ) { + specifiers.push( `{ ${importedNames.join( ', ' )} }` ); } return specifiers.length ?