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

investigate requirement of needing a default export for rendering entry points #23

Open
thescientist13 opened this issue May 8, 2022 · 1 comment
Assignees
Labels
documentation Improvements or additions to documentation question Further information is requested
Milestone

Comments

@thescientist13
Copy link
Member

thescientist13 commented May 8, 2022

Type of Change

  • Question / Documentation

Summary

Currently, wcc requires a default export from the first entry point custom element definition it parses.

For example, is you do this

// src/index.js
import './components/footer.js';
import './components/header.js';

const template = document.createElement('template');

template.innerHTML = `
  <wcc-header></wcc-header>

  <h1>Hello!</h1>

  <wcc-footer></wcc-footer>

  </main>
`;

class Home extends HTMLElement {

  connectedCallback() {
    if (!this.shadowRoot) {
      this.attachShadow({ mode: 'open' });
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
  }
}

export { Home };
const { html } = await renderToString(new URL('./src/index.js', import.meta.url));

wcc will throw this error

file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:80
  const elementInstance = new element(data); // eslint-disable-line new-cap
                          ^

TypeError: element is not a constructor
    at initializeCustomElement (file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:80:27)
    at async renderToString (file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:99:27)
    at async init (file:///Users/owenbuckley/Workspace/github/repos/wcc/build.js:38:22)

Details

Maybe it's because this doesn't call customElements.define, so we have no way to know the name? Perhaps that's the tradeoff

// THIS
customElement.define('wcc-header', Header);

// OR THIS?
export default Home

Not sure if this is the same thing, or supplemental to #117 so should review them both as part of doing either these tasks.


Somewhat related, we should better handle the case where you use a custom element, but not import it

// NO FOOTER IMPORT, but `wcc-footer` is still used in the HTML
import './components/header.js';

const template = document.createElement('template');

template.innerHTML = `
  <wcc-header></wcc-header>

  <h1>Hello!</h1>

  <wcc-footer></wcc-footer>
`;

class Home extends HTMLElement {

  connectedCallback() {
    if (!this.shadowRoot) {
      this.attachShadow({ mode: 'open' });
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
  }
}

export { Home };

which will casue wcc to throw this error

[0] file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:23
[0]         const { moduleURL } = deps[tagName];
[0]                 ^
[0]
[0] TypeError: Cannot destructure property 'moduleURL' of 'deps[tagName]' as it is undefined.
[0]     at renderComponentRoots (file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:23:17)
[0]     at renderComponentRoots (file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:36:13)
[0]     at renderComponentRoots (file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:36:13)
[0]     at async renderToString (file:///Users/owenbuckley/Workspace/github/repos/wcc/src/wcc.js:107:21)
[0]     at async file:///Users/owenbuckley/Workspace/github/repos/wcc/build.js:16:28
@thescientist13 thescientist13 added documentation Improvements or additions to documentation question Further information is requested labels May 8, 2022
@thescientist13 thescientist13 self-assigned this May 8, 2022
@thescientist13 thescientist13 added this to the 1.0 milestone May 8, 2022
@thescientist13
Copy link
Member Author

thescientist13 commented Aug 5, 2022

I suppose I was just missing the obvious here at first, but unless we pick an explicit name (named imports) then default is the most standards compliant, unassuming API we could pick. Unless we specifically dictated it as something like

class EntryComponent extends HTMLElement { ... }

export { EntryComponent }

So, unless we try to guess / enforce names, default just removes the discussion entirely it seems.

But again, maybe there is another more appropriate hint I am missing here? Maybe I am overthinking it? 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant