From f031ccc53a32cfac8649421f53f023749bbb498e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 17 Jun 2015 22:49:47 -0400 Subject: [PATCH] deconflict auto-generated default export names, convert expressions to declarations. fixes #29 --- src/Bundle.js | 7 ++++++- src/Module.js | 18 +++++++++++++++--- .../_config.js | 3 +++ .../default-function-export-conflict/foo.js | 7 +++++++ .../default-function-export-conflict/main.js | 3 +++ 5 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 test/function/default-function-export-conflict/_config.js create mode 100644 test/function/default-function-export-conflict/foo.js create mode 100644 test/function/default-function-export-conflict/main.js diff --git a/src/Bundle.js b/src/Bundle.js index 6160ebc..975314f 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -291,7 +291,12 @@ export default class Bundle { return; } - source.overwrite( statement.node.start, statement.node.declaration.start, `var ${canonicalName} = ` ); + // anonymous functions should be converted into declarations + if ( statement.node.declaration.type === 'FunctionExpression' ) { + source.overwrite( statement.node.start, statement.node.declaration.start + 8, `function ${canonicalName}` ); + } else { + source.overwrite( statement.node.start, statement.node.declaration.start, `var ${canonicalName} = ` ); + } } else { diff --git a/src/Module.js b/src/Module.js index aec96be..c0900c4 100644 --- a/src/Module.js +++ b/src/Module.js @@ -127,6 +127,8 @@ export default class Module { // export default 42; if ( node.type === 'ExportDefaultDeclaration' ) { const isDeclaration = /Declaration$/.test( node.declaration.type ); + const isAnonymous = /(?:Class|Function)Expression$/.test( node.declaration.type ); + const declaredName = isDeclaration && node.declaration.id.name; const identifier = node.declaration.type === 'Identifier' && node.declaration.name; @@ -137,6 +139,7 @@ export default class Module { declaredName, identifier, isDeclaration, + isAnonymous, isModified: false // in case of `export default foo; foo = somethingElse` }; } @@ -464,9 +467,18 @@ export default class Module { this.canonicalNames[ name ] = replacement; } - suggestName ( exportName, suggestion ) { - if ( !this.suggestedNames[ exportName ] ) { - this.suggestedNames[ exportName ] = makeLegalIdentifier( suggestion ); + suggestName ( defaultOrBatch, suggestion ) { + // deconflict anonymous default exports with this module's definitions + const shouldDeconflict = this.exports.default && this.exports.default.isAnonymous; + + if ( shouldDeconflict ) { + while ( suggestion in this.definitions ) { + suggestion = `_${suggestion}`; + } + } + + if ( !this.suggestedNames[ defaultOrBatch ] ) { + this.suggestedNames[ defaultOrBatch ] = makeLegalIdentifier( suggestion ); } } } diff --git a/test/function/default-function-export-conflict/_config.js b/test/function/default-function-export-conflict/_config.js new file mode 100644 index 0000000..d062e00 --- /dev/null +++ b/test/function/default-function-export-conflict/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'default export of anonymous function' +}; diff --git a/test/function/default-function-export-conflict/foo.js b/test/function/default-function-export-conflict/foo.js new file mode 100644 index 0000000..b635031 --- /dev/null +++ b/test/function/default-function-export-conflict/foo.js @@ -0,0 +1,7 @@ +function foo() { + return 42; +} + +export default function () { + return foo(); +} diff --git a/test/function/default-function-export-conflict/main.js b/test/function/default-function-export-conflict/main.js new file mode 100644 index 0000000..6f3d893 --- /dev/null +++ b/test/function/default-function-export-conflict/main.js @@ -0,0 +1,3 @@ +import foo from './foo'; + +assert.equal( foo(), 42 );