block by Rich-Harris e1ab25cfa6a4bcf4eb47e678133e4aad

e1ab25cfa6a4bcf4eb47

Full Screen

svelte + rollup

npm install
npm run dev

…then open index.html. Excuse the lack of folder organisation, don’t think you can have folders in a gist.

index.html

<!doctype html>
<html>
<head>
	<title>Rollup + Svelte test</title>
</head>
<body>
	<main></main>
	<script src='bundle.js'></script>
</body>
</html>

App.html

<h1>the answer is {{answer}}</h1>
<Nested foo='{{foo}}'/>

<script>
	import Nested from './Nested.html';

	export default {
		data () {
			return {
				foo: 'bar'
			};
		},

		components: {
			Nested
		}
	};
</script>

Nested.html

<p>foo is {{foo}}</p>

bundle.js

(function () {
'use strict';

function renderMainFragment$1 ( root, component ) {
	var p = document.createElement( 'p' );
	
	p.appendChild( document.createTextNode( "foo is " ) );
	var text1 = document.createTextNode( root.foo );
	p.appendChild( text1 );

	return {
		mount: function ( target, anchor ) {
			target.insertBefore( p, anchor );
		},

		update: function ( changed, root ) {
			text1.data = root.foo;
		},

		teardown: function ( detach ) {
			if ( detach ) {
				p.parentNode.removeChild( p );
			}
		}
	};
}

function Nested ( options ) {
	options = options || {};

	var component = this;
	var state = options.data || {};

	var observers = {
		immediate: Object.create( null ),
		deferred: Object.create( null )
	};

	var callbacks = Object.create( null );

	function dispatchObservers ( group, newState, oldState ) {
		for ( var key in group ) {
			if ( !( key in newState ) ) continue;

			var newValue = newState[ key ];
			var oldValue = oldState[ key ];

			if ( newValue === oldValue && typeof newValue !== 'object' ) continue;

			var callbacks = group[ key ];
			if ( !callbacks ) continue;

			for ( var i = 0; i < callbacks.length; i += 1 ) {
				var callback = callbacks[i];
				if ( callback.__calling ) continue;

				callback.__calling = true;
				callback.call( component, newValue, oldValue );
				callback.__calling = false;
			}
		}
	}

	this.fire = function fire ( eventName, data ) {
		var handlers = eventName in callbacks && callbacks[ eventName ].slice();
		if ( !handlers ) return;

		for ( var i = 0; i < handlers.length; i += 1 ) {
			handlers[i].call( this, data );
		}
	};

	this.get = function get ( key ) {
		return key ? state[ key ] : state;
	};

	this.set = function set ( newState ) {
		var oldState = state;
		state = Object.assign( {}, oldState, newState );
		
		dispatchObservers( observers.immediate, newState, oldState );
		if ( mainFragment ) mainFragment.update( newState, state );
		dispatchObservers( observers.deferred, newState, oldState );
	};

	this._mount = function mount ( target, anchor ) {
		mainFragment.mount( target, anchor );
	};

	this.observe = function ( key, callback, options ) {
		var group = ( options && options.defer ) ? observers.deferred : observers.immediate;

		( group[ key ] || ( group[ key ] = [] ) ).push( callback );

		if ( !options || options.init !== false ) {
			callback.__calling = true;
			callback.call( component, state[ key ] );
			callback.__calling = false;
		}

		return {
			cancel: function () {
				var index = group[ key ].indexOf( callback );
				if ( ~index ) group[ key ].splice( index, 1 );
			}
		};
	};

	this.on = function on ( eventName, handler ) {
		var handlers = callbacks[ eventName ] || ( callbacks[ eventName ] = [] );
		handlers.push( handler );

		return {
			cancel: function () {
				var index = handlers.indexOf( handler );
				if ( ~index ) handlers.splice( index, 1 );
			}
		};
	};

	this.teardown = function teardown ( detach ) {
		this.fire( 'teardown' );

		mainFragment.teardown( detach !== false );
		mainFragment = null;

		state = {};
	};

	this.root = options.root;
	this.yield = options.yield;

	var mainFragment = renderMainFragment$1( state, this );
	if ( options.target ) this._mount( options.target );
}

var template = (function () {
	return {
		data () {
			return {
				foo: 'bar'
			};
		},

		components: {
			Nested
		}
	};
}());

function renderMainFragment ( root, component ) {
	var h1 = document.createElement( 'h1' );
	
	h1.appendChild( document.createTextNode( "the answer is " ) );
	var text1 = document.createTextNode( root.answer );
	h1.appendChild( text1 );
	var text2 = document.createTextNode( "\n" );
	
	var nested_initialData = {
		foo: root.foo
	};
	var nested = new template.components.Nested({
		target: null,
		root: component.root || component,
		data: nested_initialData
	});

	return {
		mount: function ( target, anchor ) {
			target.insertBefore( h1, anchor );
			target.insertBefore( text2, anchor );
			nested._mount( target, anchor );
		},

		update: function ( changed, root ) {
			text1.data = root.answer;
			
			var nested_changes = {};
			
			if ( 'foo' in changed ) nested_changes.foo = root.foo;
			
			if ( Object.keys( nested_changes ).length ) nested.set( nested_changes );
		},

		teardown: function ( detach ) {
			nested.teardown( detach );
			
			if ( detach ) {
				h1.parentNode.removeChild( h1 );
				text2.parentNode.removeChild( text2 );
			}
		}
	};
}

function App ( options ) {
	options = options || {};

	var component = this;
	var state = Object.assign( template.data(), options.data );

	var observers = {
		immediate: Object.create( null ),
		deferred: Object.create( null )
	};

	var callbacks = Object.create( null );

	function dispatchObservers ( group, newState, oldState ) {
		for ( var key in group ) {
			if ( !( key in newState ) ) continue;

			var newValue = newState[ key ];
			var oldValue = oldState[ key ];

			if ( newValue === oldValue && typeof newValue !== 'object' ) continue;

			var callbacks = group[ key ];
			if ( !callbacks ) continue;

			for ( var i = 0; i < callbacks.length; i += 1 ) {
				var callback = callbacks[i];
				if ( callback.__calling ) continue;

				callback.__calling = true;
				callback.call( component, newValue, oldValue );
				callback.__calling = false;
			}
		}
	}

	this.fire = function fire ( eventName, data ) {
		var handlers = eventName in callbacks && callbacks[ eventName ].slice();
		if ( !handlers ) return;

		for ( var i = 0; i < handlers.length; i += 1 ) {
			handlers[i].call( this, data );
		}
	};

	this.get = function get ( key ) {
		return key ? state[ key ] : state;
	};

	this.set = function set ( newState ) {
		var oldState = state;
		state = Object.assign( {}, oldState, newState );
		
		dispatchObservers( observers.immediate, newState, oldState );
		if ( mainFragment ) mainFragment.update( newState, state );
		dispatchObservers( observers.deferred, newState, oldState );
		
		while ( this.__renderHooks.length ) {
			var hook = this.__renderHooks.pop();
			hook.fn.call( hook.context );
		}
	};

	this._mount = function mount ( target, anchor ) {
		mainFragment.mount( target, anchor );
	};

	this.observe = function ( key, callback, options ) {
		var group = ( options && options.defer ) ? observers.deferred : observers.immediate;

		( group[ key ] || ( group[ key ] = [] ) ).push( callback );

		if ( !options || options.init !== false ) {
			callback.__calling = true;
			callback.call( component, state[ key ] );
			callback.__calling = false;
		}

		return {
			cancel: function () {
				var index = group[ key ].indexOf( callback );
				if ( ~index ) group[ key ].splice( index, 1 );
			}
		};
	};

	this.on = function on ( eventName, handler ) {
		var handlers = callbacks[ eventName ] || ( callbacks[ eventName ] = [] );
		handlers.push( handler );

		return {
			cancel: function () {
				var index = handlers.indexOf( handler );
				if ( ~index ) handlers.splice( index, 1 );
			}
		};
	};

	this.teardown = function teardown ( detach ) {
		this.fire( 'teardown' );

		mainFragment.teardown( detach !== false );
		mainFragment = null;

		state = {};
	};

	this.root = options.root;
	this.yield = options.yield;

	this.__renderHooks = [];
	
	var mainFragment = renderMainFragment( state, this );
	if ( options.target ) this._mount( options.target );
	
	while ( this.__renderHooks.length ) {
		var hook = this.__renderHooks.pop();
		hook.fn.call( hook.context );
	}
}

window.app = new App({
	target: document.querySelector( 'main' ),
	data: {
		answer: 42
	}
});

}());

main.js

import App from './App.html';

window.app = new App({
	target: document.querySelector( 'main' ),
	data: {
		answer: 42
	}
});

package.json

{
  "devDependencies": {
    "rollup": "^0.41.4",
    "rollup-plugin-svelte": "^1.6.0",
    "rollup-watch": "^3.2.2"
  },
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w"
  }
}

rollup.config.js

import svelte from 'rollup-plugin-svelte';

export default {
	entry: 'main.js',
	dest: 'bundle.js',
	format: 'iife',
	plugins: [
		svelte()
	]
};