11ty / webc

Single File Web Components
MIT License
1.31k stars 38 forks source link

pages, bundler mode, and js/styles #55

Closed WickyNilliams closed 1 year ago

WickyNilliams commented 1 year ago

If I have my-component.webc:

<p>
  Hello, 
  <strong class="name">
    <slot></slot>
  </strong>
</p>

<script>
class MyComponent extends HTMLElement {
  constructor() {
    super()

    const name = this.querySelector(".name")
    console.log("hello", name.textContent)
  }
}
customElements.define("my-component", MyComponent)
</script>

and a page.webc:

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>hello webc!</title>
  </head>
  <body>
    <my-component>Zach</my-component>
    <my-component>Nick</my-component>
  </body>
</html>

and the following script:

import { WebC } from "@11ty/webc";

let page = new WebC();

page.defineComponents("components/**.webc");
page.setInputPath("page.webc")

const { html } = await page.compile()
console.log(html)

I end up with the styles and custom element code being included twice, once for each instance of my-component. That makes sense, since it's not in bundler mode (though it causes an exception in the browser to register a component twice).

But if i switch to bundler mode, I have my HTML stripped of all JS and CSS. That's expected also. But how can I then get the JS and CSS back into the HTML, so it's included just once?

Here's a stackblitz showing demonstrating the above: https://stackblitz.com/edit/webc-page-bundler-mode

Am I holding it wrong?

WickyNilliams commented 1 year ago

what would be cool is if i could do something like:

layout.webc:

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title @html="title"></title>
    <slot name="webc:css"></slot>
  </head>
  <body>
    <slot name="webc:html"></slot>
    <slot name="webc:js"></slot>
  </body>
</html>

page1.webc:

<layout title="page 1">
  <my-component>Nick</my-component>
</layout>

page2.webc:

<layout title="page 2">
   <my-component>Nick</my-component>
   <my-component>Zach</my-component>
</layout>

and webc knows to place the JS/CSS/HTML in the specially named slots in bundler mode

just thinking out loud here :)

WickyNilliams commented 1 year ago

Possibly related to #27

zachleat commented 1 year ago

Yeah the Eleventy plugin smooths this over a bit but I think you’re right it should be improved in WebC! Related to https://github.com/11ty/eleventy-plugin-webc/issues/11

zachleat commented 1 year ago

This shipped with v0.8.0 but I’d also call out to eleventy-plugin-bundle which is coming in the next version of eleventy-plugin-webc in https://github.com/11ty/eleventy-plugin-webc/issues/48

Please follow along over there!

Also a shout to #36 too.