diff --git a/src/Declaration.js b/src/Declaration.js index a8e192a..0601606 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -282,7 +282,7 @@ export class ExternalDeclaration { } if ( this.name === 'default' ) { - return !es6 && this.module.exportsNames ? + return this.module.exportsNamespace || ( !es6 && this.module.exportsNames ) ? `${this.module.name}__default` : this.module.name; } diff --git a/src/ExternalModule.js b/src/ExternalModule.js index 3113a5d..db9c062 100644 --- a/src/ExternalModule.js +++ b/src/ExternalModule.js @@ -27,9 +27,8 @@ export default class ExternalModule { } traceExport ( name ) { - if ( name !== 'default' && name !== '*' ) { - this.exportsNames = true; - } + if ( name !== 'default' && name !== '*' ) this.exportsNames = true; + if ( name === '*' ) this.exportsNamespace = true; return this.declarations[ name ] || ( this.declarations[ name ] = new ExternalDeclaration( this, name ) diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index b921429..ecb57ea 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -3,11 +3,12 @@ import getExportBlock from './shared/getExportBlock.js'; export default function cjs ( bundle, magicString, { exportMode }, options ) { let intro = options.useStrict === false ? `` : `'use strict';\n\n`; - const hasDefaultImport = bundle.externalModules.some( mod => mod.declarations.default); + let needsInterop = false; + // const hasDefaultImport = bundle.externalModules.some( mod => mod.declarations.default); - if (hasDefaultImport) { - intro += `function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\n`; - } + // if (hasDefaultImport) { + // intro += `function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\n`; + // } const varOrConst = bundle.varOrConst; @@ -15,18 +16,29 @@ export default function cjs ( bundle, magicString, { exportMode }, options ) { const importBlock = bundle.externalModules .map( module => { if ( module.declarations.default ) { - if (module.exportsNames) { + if ( module.exportsNamespace ) { + return `${varOrConst} ${module.name} = require('${module.id}');` + + `\n${varOrConst} ${module.name}__default = ${module.name}['default'];`; + } + + needsInterop = true; + + if ( module.exportsNames ) { return `${varOrConst} ${module.name} = require('${module.id}');` + `\n${varOrConst} ${module.name}__default = _interopDefault(${module.name});`; - } else { - return `${varOrConst} ${module.name} = _interopDefault(require('${module.id}'));`; } + + return `${varOrConst} ${module.name} = _interopDefault(require('${module.id}'));`; } else { return `${varOrConst} ${module.name} = require('${module.id}');`; } }) .join( '\n' ); + if ( needsInterop ) { + intro += `function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\n`; + } + if ( importBlock ) { intro += importBlock + '\n\n'; } diff --git a/src/finalisers/es6.js b/src/finalisers/es6.js index a86e04e..bd3f93f 100644 --- a/src/finalisers/es6.js +++ b/src/finalisers/es6.js @@ -19,7 +19,11 @@ export default function es6 ( bundle, magicString ) { }); if ( module.declarations.default ) { - specifiers.push( module.name ); + if ( module.exportsNamespace ) { + specifiersList.push([ `${module.name}__default` ]); + } else { + specifiers.push( module.name ); + } } const namespaceSpecifier = module.declarations['*'] ? `* as ${module.name}` : null; diff --git a/src/finalisers/shared/getInteropBlock.js b/src/finalisers/shared/getInteropBlock.js index a747d82..67a26d7 100644 --- a/src/finalisers/shared/getInteropBlock.js +++ b/src/finalisers/shared/getInteropBlock.js @@ -1,11 +1,17 @@ export default function getInteropBlock ( bundle ) { return bundle.externalModules .map( module => { - return module.declarations.default ? - ( module.exportsNames ? - `${bundle.varOrConst} ${module.name}__default = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};` : - `${module.name} = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};` ) : - null; + if ( !module.declarations.default ) return null; + + if ( module.exportsNamespace ) { + return `${bundle.varOrConst} ${module.name}__default = ${module.name}['default'];`; + } + + if ( module.exportsNames ) { + return `${bundle.varOrConst} ${module.name}__default = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};`; + } + + return `${module.name} = 'default' in ${module.name} ? ${module.name}['default'] : ${module.name};`; }) .filter( Boolean ) .join( '\n' ); diff --git a/test/form/import-external-namespace-and-default/_config.js b/test/form/import-external-namespace-and-default/_config.js new file mode 100644 index 0000000..5ee7b48 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'disinguishes between external default and namespace (#637)' +}; diff --git a/test/form/import-external-namespace-and-default/_expected/amd.js b/test/form/import-external-namespace-and-default/_expected/amd.js new file mode 100644 index 0000000..1f4b3f9 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/amd.js @@ -0,0 +1,9 @@ +define(['foo'], function (foo) { 'use strict'; + + var foo__default = foo['default']; + + console.log( foo.bar ); + + console.log( foo__default ); + +}); diff --git a/test/form/import-external-namespace-and-default/_expected/cjs.js b/test/form/import-external-namespace-and-default/_expected/cjs.js new file mode 100644 index 0000000..14c733e --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/cjs.js @@ -0,0 +1,8 @@ +'use strict'; + +var foo = require('foo'); +var foo__default = foo['default']; + +console.log( foo.bar ); + +console.log( foo__default ); diff --git a/test/form/import-external-namespace-and-default/_expected/es6.js b/test/form/import-external-namespace-and-default/_expected/es6.js new file mode 100644 index 0000000..5655595 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/es6.js @@ -0,0 +1,6 @@ +import * as foo from 'foo'; +import foo__default from 'foo'; + +console.log( foo.bar ); + +console.log( foo__default ); diff --git a/test/form/import-external-namespace-and-default/_expected/iife.js b/test/form/import-external-namespace-and-default/_expected/iife.js new file mode 100644 index 0000000..b2c5788 --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/iife.js @@ -0,0 +1,10 @@ +(function (foo) { + 'use strict'; + + var foo__default = foo['default']; + + console.log( foo.bar ); + + console.log( foo__default ); + +}(foo)); diff --git a/test/form/import-external-namespace-and-default/_expected/umd.js b/test/form/import-external-namespace-and-default/_expected/umd.js new file mode 100644 index 0000000..ddcdcbd --- /dev/null +++ b/test/form/import-external-namespace-and-default/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('foo')) : + typeof define === 'function' && define.amd ? define(['foo'], factory) : + (factory(global.foo)); +}(this, function (foo) { 'use strict'; + + var foo__default = foo['default']; + + console.log( foo.bar ); + + console.log( foo__default ); + +})); diff --git a/test/form/import-external-namespace-and-default/main.js b/test/form/import-external-namespace-and-default/main.js new file mode 100644 index 0000000..719a96a --- /dev/null +++ b/test/form/import-external-namespace-and-default/main.js @@ -0,0 +1,4 @@ +import foo from 'foo'; +import './other.js'; + +console.log( foo ); diff --git a/test/form/import-external-namespace-and-default/other.js b/test/form/import-external-namespace-and-default/other.js new file mode 100644 index 0000000..8149fb6 --- /dev/null +++ b/test/form/import-external-namespace-and-default/other.js @@ -0,0 +1,3 @@ +import * as foo from 'foo'; + +console.log( foo.bar );