diff --git a/src/generators/Generator.js b/src/generators/Generator.js index 4d17d55d81..a41f3903fd 100644 --- a/src/generators/Generator.js +++ b/src/generators/Generator.js @@ -266,10 +266,11 @@ export default class Generator { const imports = this.imports; const computations = []; - let defaultExport = null; - let namespace = null; const templateProperties = {}; + let namespace = null; + let hasJs = !!js; + if ( js ) { this.addSourcemapLocations( js.content ); const body = js.content.body.slice(); // slice, because we're going to be mutating the original @@ -287,38 +288,14 @@ export default class Generator { } } - defaultExport = body.find( node => node.type === 'ExportDefaultDeclaration' ); + const defaultExport = body.find( node => node.type === 'ExportDefaultDeclaration' ); if ( defaultExport ) { - const finalNode = body[ body.length - 1 ]; - if ( defaultExport === finalNode ) { - // export is last property, we can just return it - this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `return ` ); - } else { - const { declarations } = annotateWithScopes( js ); - let template = 'template'; - for ( let i = 1; declarations.has( template ); template = `template_${i++}` ); - - this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `var ${template} = ` ); - - let i = defaultExport.start; - while ( /\s/.test( source[ i - 1 ] ) ) i--; - - const indentation = source.slice( i, defaultExport.start ); - this.code.appendLeft( finalNode.end, `\n\n${indentation}return ${template};` ); - } - defaultExport.declaration.properties.forEach( prop => { templateProperties[ prop.key.name ] = prop; }); - - this.code.prependRight( js.content.start, `var ${this.alias( 'template' )} = (function () {` ); - } else { - this.code.prependRight( js.content.start, '(function () {' ); } - this.code.appendLeft( js.content.end, '}());' ); - [ 'helpers', 'events', 'components' ].forEach( key => { if ( templateProperties[ key ] ) { templateProperties[ key ].value.properties.forEach( prop => { @@ -383,10 +360,51 @@ export default class Generator { removeObjectKey( this.code, defaultExport.declaration, 'components' ); } } + + // now that we've analysed the default export, we can determine whether or not we need to keep it + let hasDefaultExport = !!defaultExport; + if ( defaultExport && defaultExport.declaration.properties.length === 0 ) { + hasDefaultExport = false; + removeNode( this.code, js.content, defaultExport ); + } + + // if we do need to keep it, then we need to generate a return statement + if ( hasDefaultExport ) { + const finalNode = body[ body.length - 1 ]; + if ( defaultExport === finalNode ) { + // export is last property, we can just return it + this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `return ` ); + } else { + const { declarations } = annotateWithScopes( js ); + let template = 'template'; + for ( let i = 1; declarations.has( template ); template = `template_${i++}` ); + + this.code.overwrite( defaultExport.start, defaultExport.declaration.start, `var ${template} = ` ); + + let i = defaultExport.start; + while ( /\s/.test( source[ i - 1 ] ) ) i--; + + const indentation = source.slice( i, defaultExport.start ); + this.code.appendLeft( finalNode.end, `\n\n${indentation}return ${template};` ); + } + } + + // user code gets wrapped in an IIFE + if ( js.content.body.length ) { + const prefix = hasDefaultExport ? `var ${this.alias( 'template' )} = (function () {` : `(function () {`; + this.code.prependRight( js.content.start, prefix ).appendLeft( js.content.end, '}());' ); + } + + // if there's no need to include user code, remove it altogether + else { + this.code.remove( js.content.start, js.content.end ); + hasJs = false; + } } return { computations, + hasJs, namespace, templateProperties }; diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index 097eabe357..404f3866e8 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -151,7 +151,7 @@ export default function dom ( parsed, source, options ) { const generator = new DomGenerator( parsed, source, name, visitors, options ); - const { computations, templateProperties, namespace } = generator.parseJs(); + const { computations, hasJs, templateProperties, namespace } = generator.parseJs(); // Remove these after version 2 if ( templateProperties.onrender ) { @@ -239,7 +239,7 @@ export default function dom ( parsed, source, options ) { ${generator.helper( 'dispatchObservers' )}( this, this._observers.post, newState, oldState ); ` ); - if ( parsed.js ) { + if ( hasJs ) { builders.main.addBlock( `[✂${parsed.js.content.start}-${parsed.js.content.end}✂]` ); } diff --git a/src/generators/server-side-rendering/index.js b/src/generators/server-side-rendering/index.js index 84740617c2..d1c4e2a193 100644 --- a/src/generators/server-side-rendering/index.js +++ b/src/generators/server-side-rendering/index.js @@ -40,7 +40,7 @@ export default function ssr ( parsed, source, options ) { const generator = new SsrGenerator( parsed, source, name, visitors, options ); - const { computations, templateProperties } = generator.parseJs(); + const { computations, hasJs, templateProperties } = generator.parseJs(); const builders = { main: new CodeBuilder(), @@ -131,7 +131,7 @@ export default function ssr ( parsed, source, options ) { }; ` ); - if ( parsed.js ) { + if ( hasJs ) { builders.main.addBlock( `[✂${parsed.js.content.start}-${parsed.js.content.end}✂]` ); }