diff --git a/src/Module.js b/src/Module.js index 324b4b8..da22cc0 100644 --- a/src/Module.js +++ b/src/Module.js @@ -433,14 +433,37 @@ export default class Module { } // split up/remove var declarations as necessary - if ( statement.node.isSynthetic ) { - // insert `var/let/const` if necessary - const declaration = this.declarations[ statement.node.declarations[0].id.name ]; - if ( !( declaration.isExported && declaration.isReassigned ) ) { // TODO encapsulate this - magicString.insert( statement.start, `${statement.node.kind} ` ); + if ( statement.node.type === 'VariableDeclaration' ) { + const declarator = statement.node.declarations[0]; + + if ( declarator.id.type === 'Identifier' ) { + const declaration = this.declarations[ declarator.id.name ]; + + if ( declaration.isExported && declaration.isReassigned ) { // `var foo = ...` becomes `exports.foo = ...` + magicString.remove( statement.start, declarator.init ? declarator.start : statement.next ); + return; + } } - magicString.overwrite( statement.end, statement.next, ';\n' ); // TODO account for trailing newlines + else { + // we handle destructuring differently, because whereas we can rewrite + // `var foo = ...` as `exports.foo = ...`, in a case like `var { a, b } = c()` + // where `a` or `b` is exported and reassigned, we have to append + // `exports.a = a;` and `exports.b = b` instead + extractNames( declarator.id ).forEach( name => { + const declaration = this.declarations[ name ]; + + if ( declaration.isExported && declaration.isReassigned ) { + magicString.insert( statement.end, `;\nexports.${name} = ${declaration.render( es6 )}` ); + } + }); + } + + if ( statement.node.isSynthetic ) { + // insert `var/let/const` if necessary + magicString.insert( statement.start, `${statement.node.kind} ` ); + magicString.overwrite( statement.end, statement.next, ';\n' ); // TODO account for trailing newlines + } } let toDeshadow = blank(); diff --git a/test/form/object-destructuring-default-values/_config.js b/test/form/object-destructuring-default-values/_config.js index 18347b6..c4ccc90 100644 --- a/test/form/object-destructuring-default-values/_config.js +++ b/test/form/object-destructuring-default-values/_config.js @@ -1,3 +1,3 @@ module.exports = { - description: 'object destructuring default values are preserved' + description: 'object destructuring default values are preserved' }; diff --git a/test/function/deconstructed-exported-vars/_config.js b/test/function/deconstructed-exported-vars/_config.js new file mode 100644 index 0000000..0451342 --- /dev/null +++ b/test/function/deconstructed-exported-vars/_config.js @@ -0,0 +1,10 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'allows destructuring in exported variable declarations, synthetic or otherwise', + babel: true, + exports: function ( exports ) { + assert.equal( exports.a, 1 ); + assert.equal( exports.d, 4 ); + } +}; diff --git a/test/function/deconstructed-exported-vars/main.js b/test/function/deconstructed-exported-vars/main.js new file mode 100644 index 0000000..a6fcd89 --- /dev/null +++ b/test/function/deconstructed-exported-vars/main.js @@ -0,0 +1,11 @@ +let { a, b } = c(), [ d, e ] = f(); + +function c () { + return { a: 1, b: 2 }; +} + +function f () { + return [ 4, 5 ]; +} + +export { a, d }; diff --git a/test/function/removes-empty-exported-vars/_config.js b/test/function/removes-empty-exported-vars/_config.js new file mode 100644 index 0000000..4df7b7d --- /dev/null +++ b/test/function/removes-empty-exported-vars/_config.js @@ -0,0 +1,8 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'removes empty exported var declarations', + exports: function ( exports ) { + assert.equal( exports.foo, 42 ); + } +}; diff --git a/test/function/removes-empty-exported-vars/main.js b/test/function/removes-empty-exported-vars/main.js new file mode 100644 index 0000000..7ebe888 --- /dev/null +++ b/test/function/removes-empty-exported-vars/main.js @@ -0,0 +1,4 @@ +var foo; +foo = 42; + +export { foo };