Open trusktr opened 4 years ago
I'll assume that the proposal was missing the export
part.
What happens if there are multiple script tags?
<definition name="my-element">
<template>....</template>
<script type="module">
export default class MyElement extends HTMLElement {
// ...
}
</script>
<script type="module">
export default class MyOtherElement extends HTMLElement {
// ...
}
</script>
</definition>
Should the <definition>
accept and execute only the first script tag? Or maybe execute any script tags like normal, but take the export only from the first script tag?
Maybe the following is for another spec, but it seems there should be a way, in general, to grab the exports of a type=module script tag, f.e.
<script type="module">
export default class MyOtherElement extends HTMLElement {
// ...
}
</script>
<script>
const s = document.querySelector('[type=module]')
// Similar to ES import():
s.import().then(m => console.log(m.default)) // logs MyOtherElement class
</script>
Or maybe also something like
<script type="module" name="MyOtherElement">
export default class MyOtherElement extends HTMLElement {
// ...
}
</script>
<script>
const s = document.querySelector('[type=module]')
// Using ES import():
import('script:MyOtherElement').then(m => console.log(m.default)) // logs MyOtherElement class
</script>
The class should indeed be export default
.
What happens if there are multiple script tags?
I think we can easily say that only the first of last module is used.
I just wanted to throw out the possibility that we could morph server rendered HTML that is rendered into the live DOM tree into a "template" for a web component that could be used by other single tags. An example of how this could be useful: A server-rendered side nav component used for the hamburger menu. Then it could "progressively" be used to define the web component. Another example would be a slide show web component, where we want to display the initial slide before all the dependencies have been loaded.
POC here.
I think the performance would be better, especially if the JavaScript may have numerous dependencies that need to load before the web component could become active.
It would also allow streaming to be utilized for the first instance of the declarative web component.
Something to note: This solution does not require that the developer write any JavaScript, not even defining a class! Just specify prop names, which can be set via attributes, which template instantiation (especially template instantiation that uses comments for placeholders ) could fill in. Basically, do as much as possible with JSON definitions (which I believe could cover a large chunk of declarative web components).
DCE does not have to use JS and IMO the "pure" DCE would be JS-less. The class would be created by the browser and use the native templating for content rendering. The element life cycle events and callbacks can be assigned either as inline onxxx
or associated by embedded SCRIPT sections, something like
<script type="element/connectedCallback" >...
with default export of callback
or
<script type="module" >document.currentScript.getRootNode().connectedCalback = function(){....}
But it would require to add currentScript
to ES6 module JS API. As of now it is only in ES5 and there is a struggle to get it approved even for inline scripts.
The <script type="module">
is optional in pure declarative case and would be needed only when there is a need to redefine the constructor. Which I hope would be less demanded when pure declarative syntax is fully functional.
@trusktr ,
Should customElements.attachTemplateAsShadow(this, state)
be separate proposal ?
I see the need for such API, but not on customElements
. Rather follow the pattern of element.attachShadow
WCCG had their spring F2F in which this was discussed. You can read the full notes of the discussion (WCCG had their spring F2F) in which this was discussed, heading entitled "Declarative Templating & Custom Elements".
This was briefly discussed as part of that topic. The consensus from present members of the WCCG was that more use cases need to be captured around this area, in order to clarify what these proposals solve.
In the following,
how does the engine know to define the
<my-element>
element using theMyElement
class?How does
type="module"
come into play here? What happens if type=module were not included?What happens if I write two classes in the script tag? F.e.
Or is the example in the proposal missing an
export
? Should it be?
Happy to propose changes to the proposal file once this is cleared up.