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

Neater approach to code generation #652

Closed
Rich-Harris opened this issue Jun 18, 2017 · 3 comments
Closed

Neater approach to code generation #652

Rich-Harris opened this issue Jun 18, 2017 · 3 comments

Comments

@Rich-Harris
Copy link
Member

The code that generates code is really quite tricky to follow. For the sake of discussion, I'll choose perhaps the easiest example:

if (generator.css && options.css !== false) {
  builders.main.addBlock(deindent`
    function ${generator.alias('add_css')} () {
      var style = ${generator.helper('createElement')}( 'style' );
      style.id = ${JSON.stringify(generator.cssId + '-style')};
      style.textContent = ${JSON.stringify(generator.css)};
      ${generator.helper('appendNode')}( style, document.head );
    }
  `);
}

There's a lot of noise there. I'm wondering about a different approach, whereby snippets are written in more natural JavaScript...

function add_css () {
  var style = createElement('style');
  style.id = __id__;
  style.textContent = __css__;
  appendNode(style, document.head);
}

...and turned into data that can be manipulated like so:

if (generator.css && options.css !== false) {
  builders.main.addBlock(addCss({
    id: JSON.stringify(generator.cssId + '-style'),
    css: JSON.stringify(generator.css)
  }));
}

Helpers can be automatically identified and aliased, and the snippets — being valid JS — can be run through Prettier etc.

We could use comment syntax as well:

function create_main_fragment (state, component) {
  /** #if variables */
  var __variables__;
  /** /if */

  return {
    /** #if key */
    key: __key__,
    /** /if */

    /** #if create */
    create: function () {
      /** #block create */
    },
    /** else */
    create: noop,
    /** /if */
  };
}

(That might need a bit more work, admittedly.)

We're already doing something vaguely along these lines with the shared helpers (figuring out which helpers depend on which other ones, etc), so I reckon this is worth exploring.

@kzc
Copy link

kzc commented Jun 18, 2017

At what point do shared helpers become a library?

@Rich-Harris
Copy link
Member Author

My take: at the point where you as a developer have to consider them separately (including worrying about which helpers are included) from your app code — in other words, never. In most cases, we're talking about things like this...

export function detachNode(node) {
  node.parentNode.removeChild(node);
}

...and I'd argue it doesn't really make sense to call that 'library code' anyway. Depends on your semantics though!

@Rich-Harris
Copy link
Member Author

Closing this in favour of #673

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

2 participants