From 53b21d1629baf3f9fc1857217b8133ff56f02342 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 29 Aug 2016 16:03:24 -0400 Subject: [PATCH] ensure intro appears before interop block (#880) --- src/Bundle.js | 6 +++--- src/finalisers/amd.js | 8 +++++--- src/finalisers/cjs.js | 6 +++--- src/finalisers/es.js | 7 +++---- src/finalisers/iife.js | 20 +++++++++++--------- src/finalisers/umd.js | 12 ++++++++---- test/form/intro-and-outro/_config.js | 3 ++- test/form/intro-and-outro/_expected/amd.js | 7 +++++-- test/form/intro-and-outro/_expected/cjs.js | 8 +++++++- test/form/intro-and-outro/_expected/es.js | 5 ++++- test/form/intro-and-outro/_expected/iife.js | 9 ++++++--- test/form/intro-and-outro/_expected/umd.js | 13 ++++++++----- test/form/intro-and-outro/main.js | 5 ++++- 13 files changed, 69 insertions(+), 40 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index ffffbf6..e458975 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -312,21 +312,21 @@ export default class Bundle { } }); - const intro = [ options.intro ] + let intro = [ options.intro ] .concat( this.plugins.map( plugin => plugin.intro && plugin.intro() ) ) .filter( Boolean ) .join( '\n\n' ); - if ( intro ) magicString.prepend( intro + '\n' ); + if ( intro ) intro += '\n'; const indentString = getIndentString( magicString, options ); const finalise = finalisers[ format ]; if ( !finalise ) throw new Error( `You must specify an output type - valid options are ${keys( finalisers ).join( ', ' )}` ); - magicString = finalise( this, magicString.trim(), { exportMode, indentString }, options ); + magicString = finalise( this, magicString.trim(), { exportMode, indentString, intro }, options ); const banner = [ options.banner ] .concat( this.plugins.map( plugin => plugin.banner ) ) diff --git a/src/finalisers/amd.js b/src/finalisers/amd.js index c04c88b..456dd86 100644 --- a/src/finalisers/amd.js +++ b/src/finalisers/amd.js @@ -3,7 +3,7 @@ import getInteropBlock from './shared/getInteropBlock.js'; import getExportBlock from './shared/getExportBlock.js'; import esModuleExport from './shared/esModuleExport.js'; -export default function amd ( bundle, magicString, { exportMode, indentString }, options ) { +export default function amd ( bundle, magicString, { exportMode, indentString, intro }, options ) { const deps = bundle.externalModules.map( quotePath ); const args = bundle.externalModules.map( getName ); @@ -17,12 +17,14 @@ export default function amd ( bundle, magicString, { exportMode, indentString }, ( deps.length ? `[${deps.join( ', ' )}], ` : `` ); const useStrict = options.useStrict !== false ? ` 'use strict';` : ``; - const intro = `define(${params}function (${args.join( ', ' )}) {${useStrict}\n\n`; + const wrapperStart = `define(${params}function (${args.join( ', ' )}) {${useStrict}\n\n`; // var foo__default = 'default' in foo ? foo['default'] : foo; const interopBlock = getInteropBlock( bundle ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); + if ( intro ) magicString.prepend( intro ); + const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); @@ -31,5 +33,5 @@ export default function amd ( bundle, magicString, { exportMode, indentString }, return magicString .indent( indentString ) .append( '\n\n});' ) - .prepend( intro ); + .prepend( wrapperStart ); } diff --git a/src/finalisers/cjs.js b/src/finalisers/cjs.js index b12d621..0ffbce8 100644 --- a/src/finalisers/cjs.js +++ b/src/finalisers/cjs.js @@ -1,9 +1,9 @@ import getExportBlock from './shared/getExportBlock.js'; import esModuleExport from './shared/esModuleExport.js'; -export default function cjs ( bundle, magicString, { exportMode }, options ) { - let intro = ( options.useStrict === false ? `` : `'use strict';\n\n` ) + - ( exportMode === 'named' ? `${esModuleExport}\n\n` : '' ); +export default function cjs ( bundle, magicString, { exportMode, intro }, options ) { + intro = ( options.useStrict === false ? intro : `'use strict';\n\n${intro}` ) + + ( exportMode === 'named' ? `${esModuleExport}\n\n` : '' ); let needsInterop = false; diff --git a/src/finalisers/es.js b/src/finalisers/es.js index a788083..4e08ce3 100644 --- a/src/finalisers/es.js +++ b/src/finalisers/es.js @@ -4,7 +4,7 @@ function notDefault ( name ) { return name !== 'default'; } -export default function es ( bundle, magicString, config, options ) { +export default function es ( bundle, magicString, { intro }, options ) { const importBlock = bundle.externalModules .map( module => { const specifiers = []; @@ -49,9 +49,8 @@ export default function es ( bundle, magicString, config, options ) { }) .join( '\n' ); - if ( importBlock ) { - magicString.prepend( importBlock + '\n\n' ); - } + if ( importBlock ) intro += importBlock + '\n\n'; + if ( intro ) magicString.prepend( intro ); const module = bundle.entryModule; diff --git a/src/finalisers/iife.js b/src/finalisers/iife.js index 319bd90..612f70f 100644 --- a/src/finalisers/iife.js +++ b/src/finalisers/iife.js @@ -16,7 +16,7 @@ function setupNamespace ( keypath ) { .join( '\n' ) + '\n'; } -export default function iife ( bundle, magicString, { exportMode, indentString }, options ) { +export default function iife ( bundle, magicString, { exportMode, indentString, intro }, options ) { const globalNameMaker = getGlobalNameMaker( options.globals || blank(), bundle.onwarn ); const name = options.moduleName; @@ -35,29 +35,31 @@ export default function iife ( bundle, magicString, { exportMode, indentString } args.unshift( 'exports' ); } - const useStrict = options.useStrict !== false ? `'use strict';` : ``; + const useStrict = options.useStrict !== false ? `${indentString}'use strict';\n\n` : ``; - let intro = `(function (${args}) {\n`; - const outro = `\n\n}(${dependencies}));`; + let wrapperIntro = `(function (${args}) {\n${useStrict}`; + const wrapperOutro = `\n\n}(${dependencies}));`; if ( exportMode === 'default' ) { - intro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${intro}`; + wrapperIntro = ( isNamespaced ? `this.` : `${bundle.varOrConst} ` ) + `${name} = ${wrapperIntro}`; } if ( isNamespaced ) { - intro = setupNamespace( name ) + intro; + wrapperIntro = setupNamespace( name ) + wrapperIntro; } // var foo__default = 'default' in foo ? foo['default'] : foo; const interopBlock = getInteropBlock( bundle ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); - if ( useStrict ) magicString.prepend( useStrict + '\n\n' ); + + if ( intro ) magicString.prepend( intro ); + const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if ( options.outro ) magicString.append( `\n${options.outro}` ); return magicString .indent( indentString ) - .prepend( intro ) - .append( outro ); + .prepend( wrapperIntro ) + .append( wrapperOutro ); } diff --git a/src/finalisers/umd.js b/src/finalisers/umd.js index 11631f5..a36db02 100644 --- a/src/finalisers/umd.js +++ b/src/finalisers/umd.js @@ -16,7 +16,9 @@ function setupNamespace ( name ) { .join( ', ' ); } -export default function umd ( bundle, magicString, { exportMode, indentString }, options ) { +const wrapperOutro = '\n\n})));'; + +export default function umd ( bundle, magicString, { exportMode, indentString, intro }, options ) { if ( exportMode !== 'none' && !options.moduleName ) { throw new Error( 'You must supply options.moduleName for UMD bundles' ); } @@ -54,7 +56,7 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, exports.noConflict = function() { global.${options.moduleName} = current; return exports; }; })()` : `(${defaultExport}factory(${globalDeps}))`; - const intro = + const wrapperIntro = `(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? ${cjsExport}factory(${cjsDeps.join( ', ' )}) : typeof define === 'function' && define.amd ? define(${amdParams}factory) : @@ -67,6 +69,8 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, const interopBlock = getInteropBlock( bundle ); if ( interopBlock ) magicString.prepend( interopBlock + '\n\n' ); + if ( intro ) magicString.prepend( intro ); + const exportBlock = getExportBlock( bundle.entryModule, exportMode ); if ( exportBlock ) magicString.append( '\n\n' + exportBlock ); if ( exportMode === 'named' ) magicString.append( `\n\n${esModuleExport}` ); @@ -75,6 +79,6 @@ export default function umd ( bundle, magicString, { exportMode, indentString }, return magicString .trim() .indent( indentString ) - .append( '\n\n})));' ) - .prepend( intro ); + .append( wrapperOutro ) + .prepend( wrapperIntro ); } diff --git a/test/form/intro-and-outro/_config.js b/test/form/intro-and-outro/_config.js index 843e554..410d586 100644 --- a/test/form/intro-and-outro/_config.js +++ b/test/form/intro-and-outro/_config.js @@ -3,6 +3,7 @@ module.exports = { options: { intro: '/* this is an intro */', outro: '/* this is an outro */', - moduleName: 'foo' + moduleName: 'foo', + external: [ 'external' ] } }; diff --git a/test/form/intro-and-outro/_expected/amd.js b/test/form/intro-and-outro/_expected/amd.js index 3c16c97..ca940e4 100644 --- a/test/form/intro-and-outro/_expected/amd.js +++ b/test/form/intro-and-outro/_expected/amd.js @@ -1,7 +1,10 @@ -define(function () { 'use strict'; +define(['external'], function (a) { 'use strict'; /* this is an intro */ - console.log( 'hello world' ); + var a__default = 'default' in a ? a['default'] : a; + + console.log( a__default ); + console.log( a.b ); var main = 42; diff --git a/test/form/intro-and-outro/_expected/cjs.js b/test/form/intro-and-outro/_expected/cjs.js index dde8f6b..6c68e67 100644 --- a/test/form/intro-and-outro/_expected/cjs.js +++ b/test/form/intro-and-outro/_expected/cjs.js @@ -1,7 +1,13 @@ 'use strict'; /* this is an intro */ -console.log( 'hello world' ); +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var a = require('external'); +var a__default = _interopDefault(a); + +console.log( a__default ); +console.log( a.b ); var main = 42; diff --git a/test/form/intro-and-outro/_expected/es.js b/test/form/intro-and-outro/_expected/es.js index 7459f70..2da2a74 100644 --- a/test/form/intro-and-outro/_expected/es.js +++ b/test/form/intro-and-outro/_expected/es.js @@ -1,5 +1,8 @@ /* this is an intro */ -console.log( 'hello world' ); +import a, { b } from 'external'; + +console.log( a ); +console.log( b ); var main = 42; diff --git a/test/form/intro-and-outro/_expected/iife.js b/test/form/intro-and-outro/_expected/iife.js index ef591fc..2c716d3 100644 --- a/test/form/intro-and-outro/_expected/iife.js +++ b/test/form/intro-and-outro/_expected/iife.js @@ -1,12 +1,15 @@ -var foo = (function () { +var foo = (function (a) { 'use strict'; /* this is an intro */ - console.log( 'hello world' ); + var a__default = 'default' in a ? a['default'] : a; + + console.log( a__default ); + console.log( a.b ); var main = 42; return main; /* this is an outro */ -}()); +}(a)); diff --git a/test/form/intro-and-outro/_expected/umd.js b/test/form/intro-and-outro/_expected/umd.js index 97b8e3e..232db4e 100644 --- a/test/form/intro-and-outro/_expected/umd.js +++ b/test/form/intro-and-outro/_expected/umd.js @@ -1,11 +1,14 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.foo = factory()); -}(this, (function () { 'use strict'; + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('external')) : + typeof define === 'function' && define.amd ? define(['external'], factory) : + (global.foo = factory(global.a)); +}(this, (function (a) { 'use strict'; /* this is an intro */ - console.log( 'hello world' ); + var a__default = 'default' in a ? a['default'] : a; + + console.log( a__default ); + console.log( a.b ); var main = 42; diff --git a/test/form/intro-and-outro/main.js b/test/form/intro-and-outro/main.js index 6054017..663ee99 100644 --- a/test/form/intro-and-outro/main.js +++ b/test/form/intro-and-outro/main.js @@ -1,3 +1,6 @@ -console.log( 'hello world' ); +import a, { b } from 'external' + +console.log( a ); +console.log( b ); export default 42;