rollup
Advanced tools
Comparing version 0.13.0 to 0.14.0
# rollup changelog | ||
## 0.14.0 | ||
* Internal refactoring | ||
* Correctly deconflict generated default export names ([#72](https://github.com/rollup/rollup/issues/72)) | ||
* Handle `export { x } from 'y'` declarations ([#74](https://github.com/rollup/rollup/issues/74)) | ||
* Dedupe named imports from external modules in ES6 bundles ([#77](https://github.com/rollup/rollup/issues/77)) | ||
## 0.13.0 | ||
@@ -4,0 +11,0 @@ |
{ | ||
"name": "rollup", | ||
"version": "0.13.0", | ||
"version": "0.14.0", | ||
"description": "Next-generation ES6 module bundler", | ||
@@ -14,3 +14,4 @@ "main": "dist/rollup.js", | ||
"build": "gobble build -f dist", | ||
"prepublish": "npm test" | ||
"prepublish": "npm test", | ||
"lint": "eslint src" | ||
}, | ||
@@ -37,2 +38,3 @@ "repository": { | ||
"console-group": "^0.1.2", | ||
"eslint": "^1.1.0", | ||
"gobble": "^0.10.1", | ||
@@ -43,3 +45,3 @@ "gobble-babel": "^5.5.8", | ||
"gobble-esperanto-bundle": "^0.2.0", | ||
"gobble-rollup": "^0.5.0", | ||
"gobble-rollup": "^0.6.0", | ||
"gobble-rollup-babel": "^0.1.0", | ||
@@ -46,0 +48,0 @@ "mocha": "^2.2.4", |
@@ -51,3 +51,3 @@ import { blank } from '../utils/object'; | ||
findDefiningScope ( name ) { | ||
if ( !!this.declarations[ name ] ) { | ||
if ( this.declarations[ name ] ) { | ||
return this; | ||
@@ -54,0 +54,0 @@ } |
@@ -33,3 +33,2 @@ import { basename, extname } from './utils/path'; | ||
this.varExports = blank(); | ||
this.toExport = null; | ||
@@ -56,6 +55,8 @@ | ||
if ( defaultExport ) { | ||
entryModule.needsDefault = true; | ||
// `export default function foo () {...}` - | ||
// use the declared name for the export | ||
if ( defaultExport.declaredName ) { | ||
entryModule.suggestName( 'default', defaultExport.declaredName ); | ||
if ( defaultExport.identifier ) { | ||
entryModule.suggestName( 'default', defaultExport.identifier ); | ||
} | ||
@@ -92,74 +93,68 @@ | ||
// TODO would be better to deconflict once, rather than per-render | ||
deconflict ( es6 ) { | ||
let definers = blank(); | ||
let conflicts = blank(); | ||
let usedNames = blank(); | ||
// ensure no conflicts with globals | ||
keys( this.assumedGlobals ).forEach( name => usedNames[ name ] = true ); | ||
let allReplacements = blank(); | ||
// Assign names to external modules | ||
this.externalModules.forEach( module => { | ||
// while we're here... | ||
allReplacements[ module.id ] = blank(); | ||
// TODO is this necessary in the ES6 case? | ||
let name = makeLegalIdentifier( module.suggestedNames['*'] || module.suggestedNames.default || module.id ); | ||
while ( definers[ name ] ) { | ||
conflicts[ name ] = true; | ||
name = `_${name}`; | ||
} | ||
definers[ name ] = [ module ]; | ||
module.name = name; | ||
this.assumedGlobals[ name ] = true; | ||
module.name = getSafeName( name ); | ||
}); | ||
// Discover conflicts (i.e. two statements in separate modules both define `foo`) | ||
this.orderedModules.forEach( module => { | ||
module.statements.forEach( statement => { | ||
const names = keys( statement.defines ); | ||
let i = this.orderedModules.length; | ||
while ( i-- ) { | ||
const module = this.orderedModules[i]; | ||
// with default exports that are expressions (`export default 42`), | ||
// we need to ensure that the name chosen for the expression does | ||
// not conflict | ||
if ( statement.node.type === 'ExportDefaultDeclaration' ) { | ||
const name = module.getCanonicalName( 'default', es6 ); | ||
// while we're here... | ||
allReplacements[ module.id ] = blank(); | ||
const isProxy = statement.node.declaration && statement.node.declaration.type === 'Identifier'; | ||
const shouldDeconflict = !isProxy || ( module.getCanonicalName( statement.node.declaration.name, es6 ) !== name ); | ||
if ( shouldDeconflict && !~names.indexOf( name ) ) { | ||
names.push( name ); | ||
} | ||
keys( module.definitions ).forEach( name => { | ||
const safeName = getSafeName( name ); | ||
if ( safeName !== name ) { | ||
module.rename( name, safeName ); | ||
allReplacements[ module.id ][ name ] = safeName; | ||
} | ||
}); | ||
} | ||
names.forEach( name => { | ||
if ( definers[ name ] ) { | ||
conflicts[ name ] = true; | ||
} else { | ||
definers[ name ] = []; | ||
} | ||
// Assign non-conflicting names to internal default/namespace export | ||
this.orderedModules.forEach( module => { | ||
if ( !module.needsDefault && !module.needsAll ) return; | ||
// TODO in good js, there shouldn't be duplicate definitions | ||
// per module... but some people write bad js | ||
definers[ name ].push( module ); | ||
}); | ||
}); | ||
}); | ||
if ( module.needsAll ) { | ||
const namespaceName = getSafeName( module.suggestedNames[ '*' ] ); | ||
module.replacements[ '*' ] = namespaceName; | ||
} | ||
// Ensure we don't conflict with globals | ||
keys( this.assumedGlobals ).forEach( name => { | ||
if ( definers[ name ] ) { | ||
conflicts[ name ] = true; | ||
if ( module.needsDefault || module.needsAll && module.exports.default ) { | ||
const defaultExport = module.exports.default; | ||
// only create a new name if either | ||
// a) it's an expression (`export default 42`) or | ||
// b) it's a name that is reassigned to (`export var a = 1; a = 2`) | ||
if ( defaultExport && defaultExport.identifier && !defaultExport.isModified ) return; // TODO encapsulate check for whether we need synthetic default name | ||
const defaultName = getSafeName( module.suggestedNames.default ); | ||
module.replacements.default = defaultName; | ||
} | ||
}); | ||
// Rename conflicting identifiers so they can live in the same scope | ||
keys( conflicts ).forEach( name => { | ||
const modules = definers[ name ]; | ||
this.orderedModules.forEach( module => { | ||
keys( module.imports ).forEach( localName => { | ||
if ( !module.imports[ localName ].isUsed ) return; | ||
if ( !this.assumedGlobals[ name ] ) { | ||
// the module closest to the entryModule gets away with | ||
// keeping things as they are, unless we have a conflict | ||
// with a global name | ||
modules.pop(); | ||
} | ||
modules.forEach( module => { | ||
const replacement = getSafeName( name ); | ||
module.rename( name, replacement ); | ||
const bundleName = this.trace( module, localName, es6 ); | ||
if ( bundleName !== localName ) { | ||
allReplacements[ module.id ][ localName ] = bundleName; | ||
} | ||
}); | ||
@@ -169,9 +164,11 @@ }); | ||
function getSafeName ( name ) { | ||
while ( conflicts[ name ] ) { | ||
while ( usedNames[ name ] ) { | ||
name = `_${name}`; | ||
} | ||
conflicts[ name ] = true; | ||
usedNames[ name ] = true; | ||
return name; | ||
} | ||
return allReplacements; | ||
} | ||
@@ -279,4 +276,7 @@ | ||
const format = options.format || 'es6'; | ||
this.deconflict( format === 'es6' ); | ||
const allReplacements = this.deconflict( format === 'es6' ); | ||
// Determine export mode - 'default', 'named', 'none' | ||
const exportMode = getExportMode( this, options.exports ); | ||
// If we have named exports from the bundle, and those exports | ||
@@ -298,4 +298,5 @@ // are assigned to *within* the bundle, we may need to rewrite e.g. | ||
let allBundleExports = blank(); | ||
let varExports = blank(); | ||
if ( format !== 'es6' ) { | ||
if ( format !== 'es6' && exportMode === 'named' ) { | ||
keys( this.entryModule.exports ).forEach( key => { | ||
@@ -307,6 +308,6 @@ const exportDeclaration = this.entryModule.exports[ key ]; | ||
if ( originalDeclaration && originalDeclaration.type === 'VariableDeclaration' ) { | ||
const canonicalName = this.entryModule.getCanonicalName( exportDeclaration.localName, false ); | ||
const canonicalName = this.trace( this.entryModule, exportDeclaration.localName, false ); | ||
allBundleExports[ canonicalName ] = `exports.${key}`; | ||
this.varExports[ key ] = true; | ||
varExports[ key ] = true; | ||
} | ||
@@ -319,3 +320,3 @@ }); | ||
this.toExport = keys( this.entryModule.exports ) | ||
.filter( key => !this.varExports[ key ] ); | ||
.filter( key => !varExports[ key ] ); | ||
@@ -326,3 +327,3 @@ | ||
this.orderedModules.forEach( module => { | ||
const source = module.render( allBundleExports, format ); | ||
const source = module.render( allBundleExports, allReplacements[ module.id ], format ); | ||
if ( source.toString().length ) { | ||
@@ -338,6 +339,16 @@ magicString.addSource( source ); | ||
return `var ${module.getCanonicalName('*', format === 'es6')} = {\n` + | ||
return `var ${module.replacements['*']} = {\n` + | ||
exportKeys.map( key => { | ||
const localName = module.exports[ key ].localName; | ||
return `${indentString}get ${key} () { return ${module.getCanonicalName(localName, format === 'es6')}; }`; | ||
let actualModule = module; | ||
let exportDeclaration = module.exports[ key ]; | ||
// special case - `export { default as foo } from './foo'` | ||
while ( exportDeclaration.linkedImport ) { | ||
actualModule = exportDeclaration.linkedImport.module; | ||
exportDeclaration = actualModule.exports[ exportDeclaration.linkedImport.name ]; | ||
} | ||
let localName = exportDeclaration.localName; | ||
localName = actualModule.replacements[ localName ] || localName; | ||
return `${indentString}get ${key} () { return ${localName}; }`; // TODO... | ||
}).join( ',\n' ) + | ||
@@ -357,3 +368,3 @@ `\n};\n\n`; | ||
// Determine export mode - 'default', 'named', 'none' | ||
exportMode: getExportMode( this, options.exports ), | ||
exportMode, | ||
@@ -467,2 +478,53 @@ // Determine indentation | ||
} | ||
trace ( module, localName, es6 ) { | ||
const importDeclaration = module.imports[ localName ]; | ||
// defined in this module | ||
if ( !importDeclaration ) { | ||
if ( localName === 'default' ) return module.defaultName(); | ||
return module.replacements[ localName ] || localName; | ||
} | ||
// defined elsewhere | ||
const otherModule = importDeclaration.module; | ||
if ( otherModule.isExternal ) { | ||
if ( importDeclaration.name === 'default' ) { | ||
return otherModule.needsNamed && !es6 ? | ||
`${otherModule.name}__default` : | ||
otherModule.name; | ||
} | ||
if ( importDeclaration.name === '*' ) { | ||
return otherModule.name; | ||
} | ||
return es6 ? | ||
importDeclaration.name : | ||
`${otherModule.name}.${importDeclaration.name}`; | ||
} | ||
if ( importDeclaration.name === '*' ) { | ||
return otherModule.replacements[ '*' ]; | ||
} | ||
if ( importDeclaration.name === 'default' ) { | ||
return otherModule.defaultName(); | ||
} | ||
const exportDeclaration = otherModule.exports[ importDeclaration.name ]; | ||
if ( exportDeclaration ) return this.trace( otherModule, exportDeclaration.localName ); | ||
for ( let i = 0; i < otherModule.exportDelegates.length; i += 1 ) { | ||
const delegate = otherModule.exportDelegates[i]; | ||
const delegateExportDeclaration = delegate.module.exports[ importDeclaration.name ]; | ||
if ( delegateExportDeclaration ) { | ||
return this.trace( delegate.module, delegateExportDeclaration.localName ); | ||
} | ||
} | ||
throw new Error( 'Could not trace binding' ); | ||
} | ||
} |
@@ -11,3 +11,2 @@ import { blank } from './utils/object'; | ||
this.canonicalNames = blank(); | ||
this.suggestedNames = blank(); | ||
@@ -30,16 +29,4 @@ | ||
getCanonicalName ( name, es6 ) { | ||
if ( name === 'default' ) { | ||
return this.needsNamed && !es6 ? `${this.name}__default` : this.name; | ||
} | ||
if ( name === '*' ) { | ||
return this.name; // TODO is this correct in ES6? | ||
} | ||
return es6 ? ( this.canonicalNames[ name ] || name ) : `${this.name}.${name}`; | ||
} | ||
rename ( name, replacement ) { | ||
this.canonicalNames[ name ] = replacement; | ||
// noop | ||
} | ||
@@ -46,0 +33,0 @@ |
@@ -1,4 +0,14 @@ | ||
import { keys } from '../utils/object'; | ||
import { blank, keys } from '../utils/object'; | ||
export default function es6 ( bundle, magicString, { exportMode }, options ) { | ||
function uniqueNames ( declarations ) { | ||
let uniques = blank(); | ||
declarations | ||
.filter( declaration => !/^(default|\*)$/.test( declaration.name ) ) | ||
.forEach( declaration => uniques[ declaration.name ] = true ); | ||
return keys( uniques ); | ||
} | ||
export default function es6 ( bundle, magicString ) { | ||
const importBlock = bundle.externalModules | ||
@@ -19,6 +29,3 @@ .map( module => { | ||
if ( module.needsNamed ) { | ||
specifiers.push( '{ ' + module.importedByBundle | ||
.filter( declaration => !/^(default|\*)$/.test( declaration.name ) ) | ||
.map( ({ name, localName }) => | ||
name === localName ? name : `${name} as ${localName}` ) | ||
specifiers.push( '{ ' + uniqueNames( module.importedByBundle ) | ||
.join( ', ' ) + ' }' ); | ||
@@ -41,3 +48,3 @@ } | ||
const canonicalName = bundle.entryModule.getCanonicalName( specifier.localName ); | ||
const canonicalName = bundle.entryModule.replacements[ specifier.localName ] || specifier.localName; | ||
@@ -44,0 +51,0 @@ if ( exportedName === 'default' ) { |
export default function getExportBlock ( bundle, exportMode, mechanism = 'return' ) { | ||
if ( exportMode === 'default' ) { | ||
return `${mechanism} ${bundle.entryModule.getCanonicalName('default')};`; | ||
const defaultExport = bundle.entryModule.exports.default; | ||
const defaultExportName = bundle.entryModule.replacements.default || | ||
defaultExport.identifier; | ||
return `${mechanism} ${defaultExportName};`; | ||
} | ||
@@ -9,5 +14,6 @@ | ||
const prop = name === 'default' ? `['default']` : `.${name}`; | ||
return `exports${prop} = ${bundle.entryModule.getCanonicalName(name)};`; | ||
name = bundle.trace( bundle.entryModule, name ); | ||
return `exports${prop} = ${name};`; | ||
}) | ||
.join( '\n' ); | ||
} |
@@ -12,3 +12,3 @@ import { dirname } from './utils/path'; | ||
const emptyArrayPromise = Promise.resolve([]); | ||
const emptyPromise = Promise.resolve(); | ||
@@ -23,7 +23,7 @@ function deconflict ( name, names ) { | ||
function isEmptyExportedVarDeclaration ( node, module, allBundleExports, es6 ) { | ||
function isEmptyExportedVarDeclaration ( node, module, allBundleExports, moduleReplacements, es6 ) { | ||
if ( node.type !== 'VariableDeclaration' || node.declarations[0].init ) return false; | ||
const name = node.declarations[0].id.name; | ||
const canonicalName = module.getCanonicalName( name, es6 ); | ||
const canonicalName = moduleReplacements[ name ] || name; | ||
@@ -56,3 +56,3 @@ return canonicalName in allBundleExports; | ||
this.statements = this._parse( ast ); | ||
this.statements = this.parse( ast ); | ||
@@ -68,3 +68,3 @@ // imports and exports, indexed by ID | ||
this.canonicalNames = blank(); | ||
this.replacements = blank(); | ||
@@ -89,4 +89,7 @@ this.definitions = blank(); | ||
const declaredName = isDeclaration && node.declaration.id.name; | ||
const identifier = node.declaration.type === 'Identifier' && node.declaration.name; | ||
const identifier = isDeclaration ? | ||
node.declaration.id.name : | ||
node.declaration.type === 'Identifier' ? | ||
node.declaration.name : | ||
null; | ||
@@ -96,4 +99,3 @@ this.exports.default = { | ||
name: 'default', | ||
localName: declaredName || 'default', | ||
declaredName, | ||
localName: identifier || 'default', | ||
identifier, | ||
@@ -116,7 +118,2 @@ isDeclaration, | ||
this.exports[ exportedName ] = { | ||
localName, | ||
exportedName | ||
}; | ||
// export { foo } from './foo'; | ||
@@ -126,6 +123,13 @@ if ( source ) { | ||
source, | ||
localName, | ||
localName: exportedName, | ||
name: localName | ||
}; | ||
} | ||
this.exports[ exportedName ] = { | ||
statement, | ||
localName, | ||
exportedName, | ||
linkedImport: source ? this.imports[ localName ] : null | ||
}; | ||
}); | ||
@@ -264,2 +268,14 @@ } | ||
defaultName () { | ||
const defaultExport = this.exports.default; | ||
if ( !defaultExport ) return null; | ||
const name = defaultExport.identifier && !defaultExport.isModified ? | ||
defaultExport.identifier : | ||
this.replacements.default; | ||
return this.replacements[ name ] || name; | ||
} | ||
findDefiningStatement ( name ) { | ||
@@ -288,2 +304,4 @@ if ( this.definitions[ name ] ) return this.definitions[ name ]; | ||
if ( module.isExternal ) return null; | ||
if ( importDeclaration.name === '*' ) return null; | ||
if ( importDeclaration.name === 'default' ) return null; | ||
@@ -306,58 +324,6 @@ const exportDeclaration = module.exports[ importDeclaration.name ]; | ||
getCanonicalName ( localName, es6 ) { | ||
// Special case | ||
if ( localName === 'default' && ( this.exports.default.isModified || !this.suggestedNames.default ) ) { | ||
let canonicalName = makeLegalIdentifier( this.id.replace( dirname( this.bundle.entryModule.id ) + '/', '' ).replace( /\.js$/, '' ) ); | ||
return deconflict( canonicalName, this.definitions ); | ||
} | ||
if ( this.suggestedNames[ localName ] ) { | ||
localName = this.suggestedNames[ localName ]; | ||
} | ||
const id = localName + ( es6 ? '-es6' : '' ); // TODO ugh this seems like a terrible hack | ||
if ( !this.canonicalNames[ id ] ) { | ||
let canonicalName; | ||
if ( this.imports[ localName ] ) { | ||
const importDeclaration = this.imports[ localName ]; | ||
const module = importDeclaration.module; | ||
if ( importDeclaration.name === '*' ) { | ||
canonicalName = module.suggestedNames[ '*' ]; | ||
} else { | ||
let exporterLocalName; | ||
if ( module.isExternal ) { | ||
exporterLocalName = importDeclaration.name; | ||
} else { | ||
const exportDeclaration = module.exports[ importDeclaration.name ]; | ||
// The export declaration of the particular name is known. | ||
if (exportDeclaration) { | ||
exporterLocalName = exportDeclaration.localName; | ||
} else { // export * from '...' | ||
exporterLocalName = importDeclaration.name; | ||
} | ||
} | ||
canonicalName = module.getCanonicalName( exporterLocalName, es6 ); | ||
} | ||
} | ||
else { | ||
canonicalName = localName; | ||
} | ||
this.canonicalNames[ id ] = canonicalName; | ||
} | ||
return this.canonicalNames[ id ]; | ||
} | ||
mark ( name ) { | ||
// shortcut cycles. TODO this won't work everywhere... | ||
// shortcut cycles | ||
if ( this.definitionPromises[ name ] ) { | ||
return emptyArrayPromise; | ||
return emptyPromise; | ||
} | ||
@@ -370,2 +336,3 @@ | ||
const importDeclaration = this.imports[ name ]; | ||
importDeclaration.isUsed = true; | ||
@@ -395,13 +362,13 @@ promise = this.bundle.fetchModule( importDeclaration.source, this.id ) | ||
if ( importDeclaration.name === 'default' && ( module.isExternal || !module.exports.default.linkedImport ) ) { // special case - exclude `export { default } from ...` | ||
module.needsDefault = true; | ||
} else if ( importDeclaration.name === '*' ) { | ||
module.needsAll = true; | ||
} else { | ||
module.needsNamed = true; | ||
} | ||
if ( module.isExternal ) { | ||
if ( importDeclaration.name === 'default' ) { | ||
module.needsDefault = true; | ||
} else if ( importDeclaration.name === '*' ) { | ||
module.needsAll = true; | ||
} else { | ||
module.needsNamed = true; | ||
} | ||
module.importedByBundle.push( importDeclaration ); | ||
return emptyArrayPromise; | ||
return emptyPromise; | ||
} | ||
@@ -415,3 +382,3 @@ | ||
return module.markAllStatements(); | ||
return module.markAllExportStatements(); | ||
} | ||
@@ -446,2 +413,7 @@ | ||
exportDeclaration.isUsed = true; | ||
if ( importDeclaration.name === 'default' ) { | ||
return exportDeclaration.statement.mark(); | ||
} | ||
return module.mark( exportDeclaration.localName ); | ||
@@ -451,45 +423,8 @@ }); | ||
// The definition is in this module | ||
else if ( name === 'default' && this.exports.default.isDeclaration ) { | ||
// We have something like `export default foo` - so we just start again, | ||
// searching for `foo` instead of default | ||
promise = this.mark( this.exports.default.name ); | ||
} | ||
else { | ||
let statement; | ||
statement = name === 'default' ? this.exports.default.statement : this.definitions[ name ]; | ||
promise = statement && !statement.isIncluded ? statement.mark() : emptyArrayPromise; | ||
// Special case - `export default foo; foo += 1` - need to be | ||
// vigilant about maintaining the correct order of the export | ||
// declaration. Otherwise, the export declaration will always | ||
// go at the end of the expansion, because the expansion of | ||
// `foo` will include statements *after* the declaration | ||
if ( name === 'default' && this.exports.default.identifier && this.exports.default.isModified ) { | ||
const defaultExportStatement = this.exports.default.statement; | ||
promise = promise.then( statements => { | ||
// remove the default export statement... | ||
// TODO could this be statements.pop()? | ||
statements.splice( statements.indexOf( defaultExportStatement ), 1 ); | ||
let i = statements.length; | ||
let inserted = false; | ||
while ( i-- ) { | ||
if ( statements[i].module === this && statements[i].index < defaultExportStatement.index ) { | ||
statements.splice( i + 1, 0, defaultExportStatement ); | ||
inserted = true; | ||
break; | ||
} | ||
} | ||
if ( !inserted ) statements.push( statement ); | ||
return statements; | ||
}); | ||
} | ||
const statement = name === 'default' ? this.exports.default.statement : this.definitions[ name ]; | ||
promise = statement && statement.mark(); | ||
} | ||
this.definitionPromises[ name ] = promise || emptyArrayPromise; | ||
this.definitionPromises[ name ] = promise || emptyPromise; | ||
return this.definitionPromises[ name ]; | ||
@@ -535,4 +470,11 @@ } | ||
// TODO rename this to parse, once https://github.com/rollup/rollup/issues/42 is fixed | ||
_parse ( ast ) { | ||
markAllExportStatements () { | ||
return sequence( this.statements, statement => { | ||
return statement.isExportDeclaration ? | ||
statement.mark() : | ||
null; | ||
}); | ||
} | ||
parse ( ast ) { | ||
// The ast can be supplied programmatically (but usually won't be) | ||
@@ -574,3 +516,3 @@ if ( !ast ) { | ||
node.declarations.forEach( ( declarator, i ) => { | ||
node.declarations.forEach( declarator => { | ||
const { start, end } = declarator; | ||
@@ -622,13 +564,9 @@ | ||
rename ( name, replacement ) { | ||
// TODO again, hacky... | ||
this.canonicalNames[ name ] = this.canonicalNames[ name + '-es6' ] = replacement; | ||
this.replacements[ name ] = replacement; | ||
} | ||
render ( allBundleExports, format ) { | ||
render ( allBundleExports, moduleReplacements, format ) { | ||
let magicString = this.magicString.clone(); | ||
let previousIndex = -1; | ||
let previousMargin = 0; | ||
this.statements.forEach( ( statement, i ) => { | ||
this.statements.forEach( statement => { | ||
if ( !statement.isIncluded ) { | ||
@@ -645,6 +583,6 @@ magicString.remove( statement.start, statement.next ); | ||
return; | ||
}; | ||
} | ||
// skip `export var foo;` if foo is exported | ||
if ( isEmptyExportedVarDeclaration( statement.node.declaration, statement.module, allBundleExports, format === 'es6' ) ) { | ||
if ( isEmptyExportedVarDeclaration( statement.node.declaration, this, allBundleExports, moduleReplacements, format === 'es6' ) ) { | ||
magicString.remove( statement.start, statement.next ); | ||
@@ -657,3 +595,3 @@ return; | ||
// (otherwise we're left with `exports.foo;`, which is useless) | ||
if ( isEmptyExportedVarDeclaration( statement.node, statement.module, allBundleExports, format === 'es6' ) ) { | ||
if ( isEmptyExportedVarDeclaration( statement.node, this, allBundleExports, moduleReplacements, format === 'es6' ) ) { | ||
magicString.remove( statement.start, statement.next ); | ||
@@ -679,8 +617,8 @@ return; | ||
.forEach( name => { | ||
const canonicalName = statement.module.getCanonicalName( name, format === 'es6' ); | ||
const bundleName = moduleReplacements[ name ] || name; | ||
if ( allBundleExports[ canonicalName ] ) { | ||
bundleExports[ name ] = replacements[ name ] = allBundleExports[ canonicalName ]; | ||
} else if ( name !== canonicalName ) { | ||
replacements[ name ] = canonicalName; | ||
if ( allBundleExports[ bundleName ] ) { | ||
bundleExports[ name ] = replacements[ name ] = allBundleExports[ bundleName ]; | ||
} else if ( bundleName !== name ) { // TODO weird structure | ||
replacements[ name ] = bundleName; | ||
} | ||
@@ -705,6 +643,5 @@ }); | ||
else if ( statement.node.type === 'ExportDefaultDeclaration' ) { | ||
const module = statement.module; | ||
const canonicalName = module.getCanonicalName( 'default', format === 'es6' ); | ||
const canonicalName = this.defaultName(); | ||
if ( statement.node.declaration.type === 'Identifier' && canonicalName === module.getCanonicalName( statement.node.declaration.name, format === 'es6' ) ) { | ||
if ( statement.node.declaration.type === 'Identifier' && canonicalName === ( moduleReplacements[ statement.node.declaration.name ] || statement.node.declaration.name ) ) { | ||
magicString.remove( statement.start, statement.next ); | ||
@@ -714,2 +651,8 @@ return; | ||
// prevent `var undefined = sideEffectyDefault(foo)` | ||
if ( canonicalName === undefined ) { | ||
magicString.remove( statement.start, statement.node.declaration.start ); | ||
return; | ||
} | ||
// anonymous functions should be converted into declarations | ||
@@ -716,0 +659,0 @@ if ( statement.node.declaration.type === 'FunctionExpression' ) { |
@@ -161,2 +161,5 @@ import { blank, keys } from './utils/object'; | ||
// disregard the `bar` in `export { foo as bar }` | ||
if ( parent.type === 'ExportSpecifier' && node !== parent.local ) return; | ||
const definingScope = scope.findDefiningScope( node.name ); | ||
@@ -371,2 +374,6 @@ | ||
} | ||
toString () { | ||
return this.module.magicString.slice( this.start, this.end ); | ||
} | ||
} |
@@ -1,3 +0,3 @@ | ||
export function unixizePath( path ) { | ||
return path.split( /[\/\\]/ ).join( '/' ); | ||
export function unixizePath ( path ) { | ||
return path.split( /[\/\\]/ ).join( '/' ); | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
778350
12
11362