diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index f39d00f5855..f16618a33e9 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -26,17 +26,17 @@ const thisProp = name => `this${keypath( name )}`; export default function iife ( bundle, magicString, { exportMode, indentString, intro, outro }, options ) { const globalNameMaker = getGlobalNameMaker( options.globals || blank(), bundle, 'null' ); - const name = options.moduleName; + const { extend, moduleName: name } = options; + const isNamespaced = name && ~name.indexOf( '.' ); + const justVariable = !extend && !isNamespaced; - if ( name && !isLegal(name) ) { + if ( name && justVariable && !isLegal(name) ) { error({ code: 'ILLEGAL_IDENTIFIER_AS_NAME', - message: `Given moduleName - ${ name } - is not legal JS identifier.` - }) + message: `Given moduleName (${name}) is not legal JS identifier. If you need this you can try --extend option` + }); } - const isNamespaced = name && ~name.indexOf( '.' ); - warnOnBuiltins( bundle ); const external = trimEmptyImports( bundle.externalModules ); @@ -50,7 +50,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString, }); } - if ( isNamespaced ) { + if ( extend ) { dependencies.unshift( `(${thisProp(name)} = ${thisProp(name)} || {})` ); args.unshift( 'exports' ); } else if ( exportMode === 'named' ) { @@ -63,7 +63,7 @@ export default function iife ( bundle, magicString, { exportMode, indentString, let wrapperIntro = `(function (${args}) {\n${useStrict}`; const wrapperOutro = `\n\n}(${dependencies}));`; - if ( exportMode !== 'none' ) { + if ( exportMode !== 'none' && !extend) { wrapperIntro = ( isNamespaced ? thisProp(name) : `${bundle.varOrConst} ${name}` ) + ` = ${wrapperIntro}`; } diff --git a/src/rollup.js b/src/rollup.js index 68c532f9943..8daa37c0e4e 100644 --- a/src/rollup.js +++ b/src/rollup.js @@ -19,6 +19,7 @@ const ALLOWED_KEYS = [ 'dest', 'entry', 'exports', + 'extend', 'external', 'footer', 'format', diff --git a/test/form/extend-exports/_config.js b/test/form/extend-exports/_config.js new file mode 100644 index 00000000000..732195b3125 --- /dev/null +++ b/test/form/extend-exports/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'extends module correctly', + options: { + extend: true, + moduleName: 'foo' + } +}; diff --git a/test/form/extend-exports/_expected/amd.js b/test/form/extend-exports/_expected/amd.js new file mode 100644 index 00000000000..8e845b5433b --- /dev/null +++ b/test/form/extend-exports/_expected/amd.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + const answer = 42; + + exports.answer = answer; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/extend-exports/_expected/cjs.js b/test/form/extend-exports/_expected/cjs.js new file mode 100644 index 00000000000..316e49a5c1b --- /dev/null +++ b/test/form/extend-exports/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const answer = 42; + +exports.answer = answer; diff --git a/test/form/extend-exports/_expected/es.js b/test/form/extend-exports/_expected/es.js new file mode 100644 index 00000000000..b460392dbdd --- /dev/null +++ b/test/form/extend-exports/_expected/es.js @@ -0,0 +1,3 @@ +const answer = 42; + +export { answer }; diff --git a/test/form/extend-exports/_expected/iife.js b/test/form/extend-exports/_expected/iife.js new file mode 100644 index 00000000000..5cddbe0c992 --- /dev/null +++ b/test/form/extend-exports/_expected/iife.js @@ -0,0 +1,8 @@ +(function (exports) { + 'use strict'; + + const answer = 42; + + exports.answer = answer; + +}((this.foo = this.foo || {}))); diff --git a/test/form/extend-exports/_expected/umd.js b/test/form/extend-exports/_expected/umd.js new file mode 100644 index 00000000000..55b0d791f77 --- /dev/null +++ b/test/form/extend-exports/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.foo = global.foo || {}))); +}(this, (function (exports) { 'use strict'; + + const answer = 42; + + exports.answer = answer; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/test/form/extend-exports/main.js b/test/form/extend-exports/main.js new file mode 100644 index 00000000000..64a32fd291e --- /dev/null +++ b/test/form/extend-exports/main.js @@ -0,0 +1 @@ +export const answer = 42; diff --git a/test/form/extend-namespaced-exports/_config.js b/test/form/extend-namespaced-exports/_config.js new file mode 100644 index 00000000000..fbd21b3f636 --- /dev/null +++ b/test/form/extend-namespaced-exports/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'extends namespaced module name', + options: { + extend: true, + moduleName: 'foo.bar.baz' + } +}; diff --git a/test/form/extend-namespaced-exports/_expected/amd.js b/test/form/extend-namespaced-exports/_expected/amd.js new file mode 100644 index 00000000000..8e845b5433b --- /dev/null +++ b/test/form/extend-namespaced-exports/_expected/amd.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + const answer = 42; + + exports.answer = answer; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/form/extend-namespaced-exports/_expected/cjs.js b/test/form/extend-namespaced-exports/_expected/cjs.js new file mode 100644 index 00000000000..316e49a5c1b --- /dev/null +++ b/test/form/extend-namespaced-exports/_expected/cjs.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const answer = 42; + +exports.answer = answer; diff --git a/test/form/extend-namespaced-exports/_expected/es.js b/test/form/extend-namespaced-exports/_expected/es.js new file mode 100644 index 00000000000..b460392dbdd --- /dev/null +++ b/test/form/extend-namespaced-exports/_expected/es.js @@ -0,0 +1,3 @@ +const answer = 42; + +export { answer }; diff --git a/test/form/extend-namespaced-exports/_expected/iife.js b/test/form/extend-namespaced-exports/_expected/iife.js new file mode 100644 index 00000000000..1b21487c31b --- /dev/null +++ b/test/form/extend-namespaced-exports/_expected/iife.js @@ -0,0 +1,10 @@ +this.foo = this.foo || {}; +this.foo.bar = this.foo.bar || {}; +(function (exports) { + 'use strict'; + + const answer = 42; + + exports.answer = answer; + +}((this.foo.bar.baz = this.foo.bar.baz || {}))); diff --git a/test/form/extend-namespaced-exports/_expected/umd.js b/test/form/extend-namespaced-exports/_expected/umd.js new file mode 100644 index 00000000000..aa4c0b0562b --- /dev/null +++ b/test/form/extend-namespaced-exports/_expected/umd.js @@ -0,0 +1,13 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.foo = global.foo || {}, global.foo.bar = global.foo.bar || {}, global.foo.bar.baz = global.foo.bar.baz || {}))); +}(this, (function (exports) { 'use strict'; + + const answer = 42; + + exports.answer = answer; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/test/form/extend-namespaced-exports/main.js b/test/form/extend-namespaced-exports/main.js new file mode 100644 index 00000000000..64a32fd291e --- /dev/null +++ b/test/form/extend-namespaced-exports/main.js @@ -0,0 +1 @@ +export const answer = 42; diff --git a/test/form/module-name-scoped-package/_config.js b/test/form/module-name-scoped-package/_config.js index 56818817923..5d2d240e9d7 100644 --- a/test/form/module-name-scoped-package/_config.js +++ b/test/form/module-name-scoped-package/_config.js @@ -1,6 +1,7 @@ module.exports = { description: 'allows module name with dashes to be added to the global object', options: { + extend: true, moduleName: '@scoped/npm-package' } }; diff --git a/test/form/module-name-wat/_expected/iife.js b/test/form/module-name-wat/_expected/iife.js index 2f7b7b24015..5d377d98182 100644 --- a/test/form/module-name-wat/_expected/iife.js +++ b/test/form/module-name-wat/_expected/iife.js @@ -1,11 +1,11 @@ this.foo = this.foo || {}; this.foo['@scoped/npm-package'] = this.foo['@scoped/npm-package'] || {}; this.foo['@scoped/npm-package'].bar = this.foo['@scoped/npm-package'].bar || {}; -(function (exports) { +this.foo['@scoped/npm-package'].bar['why-would-you-do-this'] = (function (exports) { 'use strict'; let foo = 'foo'; exports.foo = foo; -}((this.foo['@scoped/npm-package'].bar['why-would-you-do-this'] = this.foo['@scoped/npm-package'].bar['why-would-you-do-this'] || {}))); +}({})); diff --git a/test/form/module-name-with-dashes/_config.js b/test/form/module-name-with-dashes/_config.js index c466b887cd3..5a5ec8669fa 100644 --- a/test/form/module-name-with-dashes/_config.js +++ b/test/form/module-name-with-dashes/_config.js @@ -1,6 +1,7 @@ module.exports = { description: 'allows module name with dashes to be added to the global object', options: { + extend: true, moduleName: 'module-name-with-dashes' } }; diff --git a/test/form/namespaced-named-exports/_expected/iife.js b/test/form/namespaced-named-exports/_expected/iife.js index 69637e91324..4043b2692f9 100644 --- a/test/form/namespaced-named-exports/_expected/iife.js +++ b/test/form/namespaced-named-exports/_expected/iife.js @@ -1,10 +1,10 @@ this.foo = this.foo || {}; this.foo.bar = this.foo.bar || {}; -(function (exports) { +this.foo.bar.baz = (function (exports) { 'use strict'; var answer = 42; exports.answer = answer; -}((this.foo.bar.baz = this.foo.bar.baz || {}))); +}({})); diff --git a/test/test.js b/test/test.js index dfc78072346..d1c0447fbbd 100644 --- a/test/test.js +++ b/test/test.js @@ -136,7 +136,7 @@ describe( 'rollup', function () { return rollup.rollup({ entry: 'x', plUgins: [] }).then( () => { throw new Error( 'Missing expected error' ); }, err => { - assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, amd, banner, cache, context, dest, entry, exports, external, footer, format, globals, indent, interop, intro, legacy, moduleContext, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, pureExternalModules, sourceMap, sourceMapFile, targets, treeshake, useStrict, watch' ); + assert.equal( err.message, 'Unexpected key \'plUgins\' found, expected one of: acorn, amd, banner, cache, context, dest, entry, exports, extend, external, footer, format, globals, indent, interop, intro, legacy, moduleContext, moduleName, noConflict, onwarn, outro, paths, plugins, preferConst, pureExternalModules, sourceMap, sourceMapFile, targets, treeshake, useStrict, watch' ); }); });