Merge pull request #354 from taylorzane/api-create-component

API to create and return a component constructor
pull/357/head
Rich Harris 8 years ago committed by GitHub
commit 415aed70e7

@ -7,6 +7,7 @@ export default function getIntro ( format, options, imports ) {
if ( format === 'cjs' ) return getCjsIntro( options, imports );
if ( format === 'iife' ) return getIifeIntro( options, imports );
if ( format === 'umd' ) return getUmdIntro( options, imports );
if ( format === 'eval' ) return getEvalIntro( options, imports );
throw new Error( `Not implemented: ${format}` );
}
@ -60,6 +61,10 @@ function getUmdIntro ( options, imports ) {
}(this, (function (${paramString( imports )}) { 'use strict';` + '\n\n';
}
function getEvalIntro ( options, imports ) {
return `(function (${paramString( imports )}) { 'use strict';\n\n`;
}
function paramString ( imports ) {
return imports.length ? ` ${imports.map( dep => dep.name ).join( ', ' )} ` : '';
}

@ -18,6 +18,11 @@ export default function getOutro ( format, name, options, imports ) {
return `return ${name};\n\n}(${globals.join( ', ' )}));`;
}
if ( format === 'eval' ) {
const globals = getGlobals( imports, options );
return `return ${name};\n\n}(${globals.join( ', ' )}));`;
}
if ( format === 'umd' ) {
return `return ${name};\n\n})));`;
}

@ -46,4 +46,28 @@ export function compile ( source, _options ) {
return compiler( parsed, source, options, names );
}
export function create ( source, _options = {} ) {
_options.format = 'eval';
const compiled = compile( source, _options );
if ( !compiled || !compiled.code ) {
return;
}
let result;
try {
result = ( 1, eval )( compiled.code );
} catch ( err ) {
if ( _options.onerror ) {
_options.onerror( err );
} else {
throw err;
}
return;
}
return result;
}
export { parse, validate, version as VERSION };

@ -0,0 +1,40 @@
import deindent from '../src/utils/deindent.js';
import assert from 'assert';
import { svelte } from './helpers.js';
describe( 'create', () => {
it( 'should return a component constructor', () => {
const source = deindent`
<div>{{prop}}</div>
`;
const component = svelte.create( source );
assert( component instanceof Function );
});
it( 'should throw error when source is invalid ', done => {
const source = deindent`
<div>{{prop}</div>
`;
const component = svelte.create( source, {
onerror: () => {
done();
}
});
assert.equal( component, undefined );
});
it( 'should return undefined when source is invalid ', () => {
const source = deindent`
<div>{{prop}</div>
`;
const component = svelte.create( source, {
onerror: () => {}
});
assert.equal( component, undefined );
});
});

@ -63,6 +63,21 @@ function testIife ( code, name, globals, html ) {
});
}
function testEval ( code, name, globals, html ) {
const fn = new Function( Object.keys( globals ), `return ${code};` );
return env().then( window => {
const SvelteComponent = fn( ...Object.keys( globals ).map( key => globals[ key ] ) );
const main = window.document.body.querySelector( 'main' );
const component = new SvelteComponent({ target: main });
assert.htmlEqual( main.innerHTML, html );
component.destroy();
});
}
describe( 'formats', () => {
before( setupHtmlEqual );
@ -175,4 +190,31 @@ describe( 'formats', () => {
.then( () => testIife( code, 'Foo', { answer: 42 }, `<div>42</div>` ) );
});
});
describe( 'eval', () => {
it( 'generates a self-executing script that returns the component on eval', () => {
const source = deindent`
<div>{{answer}}</div>
<script>
import answer from 'answer';
export default {
data () {
return { answer };
}
};
</script>
`;
const { code } = svelte.compile( source, {
format: 'eval',
globals: {
answer: 'answer'
}
});
return testEval( code, 'Foo', { answer: 42 }, `<div>42</div>` );
});
});
});

Loading…
Cancel
Save