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

opt out of top level wrapping entry tag name when using renderToString #114

Closed
thescientist13 opened this issue Mar 23, 2023 · 2 comments · Fixed by #115
Closed

opt out of top level wrapping entry tag name when using renderToString #114

thescientist13 opened this issue Mar 23, 2023 · 2 comments · Fixed by #115
Assignees
Labels
0.8.0 documentation Improvements or additions to documentation feature New feature or request

Comments

@thescientist13
Copy link
Member

thescientist13 commented Mar 23, 2023

Type of Change

Feature

Summary

With renderToString currently, if you have a custom element that has a customElements.define call in it, e.g.

export default class MyComponent extends HTMLElement {
  // ...
}

customElements.define('my-component', MyComponent);

The HTML string produced will come out with a wrapping tag for MyComponent

<my-component>
  <!-- rendered html -->
</my-component>

Details

The issue is two fold

  1. if you're working in a system that will create single artifacts / bundles (like Serverless / Edge) functions
  2. And you're have other components you import with their own customElements.define statement

Even if you have no define call for MyComponent

import './foo.component.js';

export default class MyComponent extends HTMLElement {
  // ...
}

Your bundled code is going to have something like this

import './foo.component.js';

export class FooComponent extends HTMLElement {
  // ...
}

customElements.define('foo-component', FooComponent);

export default class MyComponent extends HTMLElement {
  // ...
}

The rendered HTML will come out like this now, because WCC just looks for the first customElements.define call it sees in the file

<foo-component>
  <my-component>
    <!-- rendered HTML -->
  </my-component>
</foo-component>

So in some cases, the wrapping my be warrented / desired, in other cases not. Probably best to give control to that so in bundling / single file cases, the final output can be better managed

@thescientist13 thescientist13 added documentation Improvements or additions to documentation feature New feature or request labels Mar 23, 2023
@thescientist13 thescientist13 self-assigned this Mar 23, 2023
@thescientist13
Copy link
Member Author

thescientist13 commented Mar 23, 2023

I know overriding with a flag seems like a quick escape hatch (but it works!) but otherwise, given this type of entry module

import './foo.component.js';

export class FooComponent extends HTMLElement {
  // ...
}

customElements.define('foo-component', FooComponent);

export default class MyComponent extends HTMLElement {
  // ...
}

How would you know that MyComponent is the entry point? I suppose it could map class definitions to usages of define for a process of elimination? Maybe some overlap with #23 🤔

I wonder if this will also mess with the definition return value?

@thescientist13
Copy link
Member Author

thescientist13 commented Mar 23, 2023

So yeah, top metadata definitions get a little compromised here as well in this "big bundle" scenario.

So given this input

class Navigation extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `
      <nav>
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/artists">Artists</a></li>
        <ul>
      </nav>
    `;
  }
}

customElements.define('wcc-navigation', Navigation);

class Header extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `
      <header class="header">>
        <h4>My Personal Blog</h4>
      </header>
    `;
  }
}

export default Header;

This is the current metadata output

{
  html: '\n' +
    '      <wcc-navigation>\n' +
    '        \n' +
    '      <header class="header">&gt;\n' +
    '        <h4>My Personal Blog</h4>\n' +
    '      </header>\n' +
    '    \n' +
    '      </wcc-navigation>\n' +
    '    ',
  metadata: [
    'wcc-navigation': {
      instanceName: 'Navigation',
      moduleURL: [URL],
      source: 'class Navigation extends HTMLElement {\n' +
        '    connectedCallback() {\n' +
        '        this.innerHTML = `\n' +
        '      <nav>\n' +
        '        <ul>\n' +
        '          <li><a href="/">Home</a></li>\n' +
        '          <li><a href="/about">About</a></li>\n' +
        '          <li><a href="/artists">Artists</a></li>\n' +
        '        <ul>\n' +
        '      </nav>\n' +
        '    `;\n' +
        '    }\n' +
        '}\n' +
        "customElements.define('wcc-navigation', Navigation);\n" +
        'class Header extends HTMLElement {\n' +
        '    connectedCallback() {\n' +
        '        this.innerHTML = `\n' +
        '      <header class="header">>\n' +
        '        <h4>My Personal Blog</h4>\n' +
        '      </header>\n' +
        '    `;\n' +
        '    }\n' +
        '}\n' +
        'export default Header;',
      url: [URL],
      isEntry: true
    }
  ]
}

I wonder if default export detection should be used instead and / or a better way to rethink how to approach metadata tracking?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.8.0 documentation Improvements or additions to documentation feature New feature or request
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

1 participant