lit SSR
简单记录 WebComponent SSR 的实现,以及使用 lit hydrate 的来做客户端 patch.
Template shadowroot
WebComponents 的 SSR 基本原理是通过 template shadowroot 属性实现的。
<my-element>
<template shadowroot="open" shadowrootmode="open">
<style>* { color: #f00; }</style>
<div>hello world</div>
</template>
</my-element>
以上代码,template 会被 clone 并 attch 到新建的 shadowdom 上。
在线 Demo:https://systemjs.1688.com/krump/schema/2442.html
Lit Component
编写 my-element-ssr 组件。
import { LitElement, html, unsafeCSS } from 'lit'
import { customElement, state } from 'lit/decorators.js'
@customElement('my-element-ssr')
class MyElement extends LitElement {
static styles = unsafeCSS('* { color: red; }')
@state({ type: Number })
accessor count = 0;
click () {
this.count++
}
render () {
return html`<div>hello world</div><button @click=${this.click}>count ${this.count}</button>`;
}
}
使用 rollup.config.js 将部分 decorator、accesser 做兼容处理。
最终打成一个 ESM 兼容模块,element.js
Lit SSR
参考 lit-ssr
import {render} from '@lit-labs/ssr';
import {collectResultSync} from '@lit-labs/ssr/lib/render-result.js';
const result = render(html`<my-element-ssr></my-element-ssr>`);
// Throws if `result` contains a Promise!
const html = collectResultSync(result);
得到 html SSR 后的代码如下:
<my-element-ssr>
<template shadowroot="open" shadowrootmode="open">
<style>* { color: red; }</style>
<!--lit-part zwZEgz88vW4=-->
<!--SSR 后里面的内容可以再次修改,后续的比对是组件内的模板 strings 和上面的这个 digest -->
<div>hello world</div>
<!--lit-node 1-->
<button >
count
<!--lit-part-->0<!--/lit-part-->
</button>
<!--/lit-part-->
</template>
</my-element-ssr>
Lit Hydrate
Hydrate 原理是通过对 template 做 digest 并 patch SSR 结果上。
digest 后的内容类似 <!--lit-part zwZEgz88vW4=-->
, SSR 的结果会和当前 client 组件的 template strings 做对比。如果对比成功,就走 patch 逻辑,如果对比失败,就会做 append 逻辑。
digest 的代码实现:digestForTemplateResult
在线 Demo https://systemjs.1688.com/krump/schema/2444.html
兼容 chrome 70
entry 代码
import { hasNativeDeclarativeShadowRoots, hydrateShadowRoots, } from '@webcomponents/template-shadowroot/template-shadowroot.js';
import { LitElement } from 'lit'
if (!hasNativeDeclarativeShadowRoots()) {
hydrateShadowRoots(document.body);
}
import('@lit-labs/ssr-client/lit-element-hydrate-support.js').then(
() => {
window.litElementHydrateSupport({ LitElement })
import('./element.js');
}
)
Vite 配置,并做打包构建 vite.config.js
React SSR with WebComponent
- https://systemjs.1688.com/krump/schema/2451.html