-
Notifications
You must be signed in to change notification settings - Fork 12
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
[SSR] DOM Shim Specification and / or Polyfill #55
Comments
May be something useful to learn from https://github.com/enhance-dev/enhance-ssr-wasm. It's a little disappointing that the default tooling there seems to make up its own interpretation of DOM, custom elements, and slots, but hopefully that's an implementation detail and not a fixed requirement as the breadth of impact a tool like that could have is quite exciting. |
Related, I don't think their DOM implementation is complete yet, but I wonder if a more modular browser architecture, like https://servo.org/, might position the ability to use a full DOM implementation in more interesting locations... |
missing prior art: https://github.com/enhance-dev/enhance-ssr |
sorry how does this have a 'made up interpretation of DOM???' if so we'd consider that a bug. otherwise I'd consider that statement FUD. fwiw Enhance is based on Parse5 which tmk is a spec compliant dom parser. |
We have an SSR implementation in Interestingly, our current list of shims differs from yours a bit; we don't support |
@brianleroux I think what was meant by this, if I'm understanding correctly, and of I didn't miss anything, is that looking here: https://github.com/enhance-dev/enhance-ssr/blob/main/index.mjs there does not appear to be any DOM APIs shimmed. So basically the library works specifically for Enhance elements, but not generically for elements made with any Custom Element framework. The idea is that a basic set of shimmed DOM APIs (not something much fuller like jsdom or undom) would end up being useful for a wide range of elements from different libs. Enhance SSR has the mechanics, but maybe it just needs a layer of DOM shim to achieve the goals in this thread. |
Indeed there are some shimmed apis running noop functions in this implementation. You can still run full WC definitions per https://enhance.dev/docs/conventions/components At any rate, the majority of elements frankly don't require much more. Backend code isn't going to get click events etc. |
For clarity, when I say that Enhance SSR "seems to make up its own interpretation of DOM, custom elements, and slots" it is because of the way it chooses, to convert this code to this code when deploying the page:
Therein you see a holely non-DOM interpretation of how to manage the use of a Full disclosure, I do not know if this is a requirement of the underlying SSR library or of the Enhance framework, as the documentation around this feature is still under development. I'd be very happy to hear that this sort of conversion was specific to the way Enhance the meta-framework leverages Enhance SSR and not of the SSR library itself. However, a DOM Shim, while certainly deserving of no-ops and workarounds for performance and delivery environment, should likely not change the DOM spec if it intends to be interoperable between various library and meta-framework approaches. |
@Westbrook this is really great, appreciate you trying Enhance! I think you are misunderstanding how things are running. Code you linked in the elements folder runs server-side (which is perfect for your use case of a header). We implement the slotted algorithm to spec (but if you found a bug there please let us know). We fully expect and want code that runs server-side to come down to the client fully expanded. Thats the point! I ack this is probably the opposite of how the mental model for WC works. If you want to have preserved slots on the client-side too check out the documentation for Components which also can expand server-side and then pick up where you left off with a template client-side for additional DOM updates). I hope that clears things up but if not please let me know. We really are hoping to get more people on board with Web Components and runtime SSR that expands elements is a crucial capability for making that happen. Appreciate your help in clarifications to make this stuff better for the next person. |
Here is an example of an Enhance component that is both SSR and CSR capable. import CustomElement from '@enhance/custom-element'
export default class MyCard extends CustomElement {
connectedCallback() {
this.heading = this.querySelector('h5')
}
render({ html, state }) {
const { attrs={} } = state
const { title='default' } = attrs
return html`
<style>
// omitted for brevity. See: https://enhance.dev/docs/conventions/components#%40enhance%2Fcustom-element
</style>
<slot name="image"></slot>
<div class="card-body font-sans">
<h5 class="card-title">${title}</h5>
<slot></slot>
</div>
`
}
static get observedAttributes() {
return [ 'title' ]
}
titleChanged(value) {
this.heading.textContent = value
}
}
customElements.define('my-card', MyCard)
On the server, we need to parse the entire file, but we only ever call the So far we've only required:
|
Really cool to see how the custom element APIs could be leveraged to author components in both SSR and CSR in Enhance. I echo @Westbrook's comments though about actionable prototypes/proposals mirroring in-browser DOM behavior…aka |
Sorry @jaredcwhite not following what you saying here. Can you provide a concrete example ? Fairly certain we support whatever you've done normally with client render. Transpiling is absolutely something we can do but it's all optin. |
Overview
As "Web Components" itself is an umbrella label for a subset of web standards and APIs native to browsers, it is an exercise left up to developers who want to server-render web components to shim the DOM themselves on the server, typically in a JavaScript (e.g. NodeJS) runtime. It would be nice as a community if we could define what a common set of reasonable Web Components and Web Components adjacent APIs for the server-side would like.
This could just be a documented spec / reference, or even a package that can be distributed out on npm for libraries and frameworks and to leverage.
Specification
I think first would be establishing what we would consider a reasonable set of shims to be for a server environment.
At the most basic, that would seem to include:
window
/document
customElements.[define|get]
HTMLElement
addEventListener
(no-op?)HTMLTemplateElement
attachShadow
.[get|set|has]Attribute
<template>
/DocumentFragment
Shared Polyfill
Much like the @webcomponentsjs family of polyfills, it would be nice for this CG to maintain / contribute this as a library that could be published to npm.
It would be nice if this is something that could be extended from so if libraries and frameworks want to add additional support on top of the baseline, they can offer that.
Prior Art
(please comment below and share others!)
(who knows, maybe we even "upstream" this into the WinterCG spec! 🤩 )
The text was updated successfully, but these errors were encountered: