Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global Svelte Method #67

Closed
shshaw opened this issue Nov 30, 2016 · 3 comments
Closed

Global Svelte Method #67

shshaw opened this issue Nov 30, 2016 · 3 comments

Comments

@shshaw
Copy link

shshaw commented Nov 30, 2016

Love the idea of Svelte and see a lot of great benefits for Javascript plugin authors and any developer concerned about performance & file size.

In cases with multiple Svelte components on one page or nested components, it seems like Svelte could benefit from having a global method that could be included once per page / plugin, rather than repeating the SveltComponent function each time. The output of Svelte CLI could have an option to inline the Svelt method into the output, or keep it separate to be included via import or in a global scope.

As a possible implementation of this, I've modified the scoped style example output as such:

Global method that returns a SvelteComponent:

function Svelte(renderMainFragment, options = {}) {
  
  var cssToAdd = options.css;
  var template = options.template;

  function SvelteComponent( options ) {
    // Factory method as suggested in #55, negating the need for `new`
    if ( !(this instanceof SvelteComponent) ) { return new SvelteComponent(options); }

    if ( cssToAdd ) { 
      Svelte.addCss(cssToAdd); 
      cssToAdd = null; 
    }

    // Usual SvelteComponent output
  }

  if ( template ) { SvelteComponent.prototype = template.methods; }

  return SvelteComponent;
}

Svelte.addCss = function(css) {
  var style = document.createElement( 'style' );
  style.textContent = css;
  document.head.appendChild( style );
}

// Other methods could be added to `Svelte` for 

Example of a component using the global method:

var Component = (function(){
  
  function renderMainComponent( root, component, target ) {
    var div = document.createElement( 'div' );
    div.setAttribute( 'svelte-2260578508', '' );
    div.className = "foo";

    var text = document.createTextNode( "Big red Comic Sans" );
    div.appendChild( text );

    target.appendChild( div )

    return {
      update: function ( changed, root ) {

      },

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

        text.parentNode.removeChild( text );
      }
    };
  }

  return Svelte(renderMainComponent, {
    // template would be included here if needed as `template: template`,
    css: ".foo[svelte-2260578508], [svelte-2260578508] .foo {\n    color: red;\n    font-size: 2em;\n    font-family: 'Comic Sans MS';\n  }\n"
  });
})();

var e = document.createElement('div');
var c = Component({ target: e });
document.body.appendChild(e);

Or for Webpack / ES6 imports:

  import Svelte from './Svelte';
  
  function renderMainComponent(root, component, target ) {
    ...
  }

  export default Svelt(renderMainComponent);

The naming conventions and exact setup may not be right, but the general idea is all I'm trying to convey.

File size for individual components with the global method included shouldn't be impacted much, but the benefits for multiple components will be huge. I don't think this is straying into "framework" territory, but is simply helpful when multiple Svelte components are being used.

@PaulBGD
Copy link
Member

PaulBGD commented Dec 1, 2016

One issue with this is that one of the goals of Svelte is to create simple modules that can be required and don't have a dependency on a version'd piece of code.

The only way I could see this being useful is if we had the option of exporting modules without the stuff included in the global Svelte method and then insert the global Svelte method ourselves.

@shshaw
Copy link
Author

shshaw commented Dec 1, 2016

That's what I meant by

The output of Svelte CLI could have an option to inline the Svelt method into the output, or keep it separate to be included via import or in a global scope.

This way, if you are building a site with Svelte components, there isn't a lot of repeated weight (which gzipping should negate, but will still have a performance tax).

@Rich-Harris
Copy link
Member

Closing this in favour of #9. We do indeed want deduplication – the best way to achieve it would be via app-level bundlers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants