@enhance/ssr

中文文档
4.0.3发布于 2024/07/23Apache-2.0ES Module近 30 天下载 3135

Server-side rendering for custom elements with template and slots support

原始使用文档
文档目录12 节
  1. Install
  2. Usage
  3. An example custom element template for use in Server Side R…
  4. Render function
  5. Store
  6. Element template
  7. Slots
  8. Transforms
  9. context
  10. instanceID
  11. bodyContent
  12. Integration with <html> , <head> , and <body> elements

Enhance SSR

Server side render for Custom Elements.

Enhance enables a web standards based workflow that embraces the platform by supporting Custom Elements and slot syntax.

Install

npm i @enhance/ssr

Usage

import HelloWorld from './path/to/elements/hello-world.mjs'
import enhance from '@enhance/ssr'
const html = enhance({
  elements: {
    'hello-world': HelloWorld
  }
})
console.log(html`<hello-world greeting="Well hi!"></hello-world>`)

An example custom element template for use in Server Side Rendering

Elements are pure functions that are passed an object containing an html function used to expand custom elements and a state object comprised of attrs which are the attributes set on the custom element and a store object that contains application state.

export default function HelloWorld({ html, state }) {
  const { attrs } = state
  const { greeting='Hello World' } = attrs
  return html`
    <style scope="global">
      h1 {
        color: red;
      }
    </style>

    <h1>${greeting}</h1>
  `
}

The rendered output

<head>
  <style scope="global">
    h1 {
      color: red;
    }
  </style>
</head>

<body>
<hello-world>
  <h1>Hello World</h1>
</hello-world>
</body>

Render function

You can also use an object that exposes a render function as your template. The render function will be passed the same arguments { html:function, state:object }.

{
  attrs: [ 'label' ],
  init(el) {
    el.addEventListener('click', el.click)
  },
  render({ html, state }) {
    const { attrs={} } = state
    const { label='Nope' } = attrs
    return html`
    <pre>
      ${JSON.stringify(state)}
    </pre>
    <button>${ label }</button>
    `
  },
  click(e) {
    console.log('CLICKED')
  },
  adopted() {
    console.log('ADOPTED')
  },
  connected() {
    console.log('CONNECTED')
  },
  disconnected() {
    console.log('DISCONNECTED')
  }
}

Use these options objects with the enhance custom element factory

Store

Supply initital state to enhance and it will be passed along in a store object nested inside the state object.

Node

import MyStoreData from './path/to/elements/my-store-data.mjs'
import enhance from '@enhance/ssr'
const html = enhance({
  elements: {
    'my-store-data': MyStoreData
  },
  initialState: { apps: [ { users: [ { name: 'tim', id: 001 }, { name: 'kim', id: 002 } ] } ] }
})
console.log(html`<my-store-data app-index="0" user-index="1"></my-store-data>`)

Element template

export default function MyStoreData({ html, state }) {
  const { attrs, store } = state
  const appIndex = attrs['app-index']
  const userIndex = attrs['user-index']
  const { id='', name='' } = store?.apps?.[appIndex]?.users?.[userIndex] || {}
  return `
<div>
  <h1>${name}</h1>
  <h1>${id}</h1>
</div>
  `
}

The store is used to pass state to all components in the tree.

Slots

Enhance supports the use of slots in your custom element templates.

export default function MyParagraph({ html }) {
  return html`
<p>
  <slot name="my-text">
    My default text
  </slot>
</p>
  `
}

You can override the default text by adding a slot attribute with a value that matches the slot name you want to replace.

<my-paragraph>
  <span slot="my-text">Let's have some different text!</span>
</my-paragraph>

Unnamed slots

Enhance supports unnamed slots for when you want to create a container element for all non-slotted child nodes.

export default function MyButton({ html }) {
  return html`
<button>
  <slot>Submit</slot>
</button>
  `
}
<my-button></my-button>

<my-button>Save</my-button>

Transforms

Enhance supports the inclusion of script and style transform functions. You add a function to the array of scriptTransforms and/or styleTransforms and are able to transform the contents however you wish, just return your desired output.

import enhance from '@enhance/ssr'

const html = enhance({
  elements: {
    'my-transform-script': MyTransformScript
  },
  scriptTransforms: [
    function({ attrs, raw }) {
      // raw is the raw text from inside the script tag
      // attrs are the attributes from the script tag
      return raw + ' yolo'
    }
  ],
  styleTransforms: [
    function({ attrs, raw }) {
      // raw is the raw text from inside the style tag
      // attrs are the attributes from the style tag
      const { scope } = attrs
      return `
      /* Scope: ${ scope } */
      ${ raw }
      `
    }
  ]
})

function MyTransformScript({ html }) {
  return html`
<style scope="component">
  :host {
    display: block;
  }
</style>
<h1>My Transform Script</h1>
<script type=module>
  class MyTransformScript extends HTMLElement {
    constructor() {
      super()
    }
  }
  customElements.define('my-transform-script', MyTransformScript)
</script>
  `
}

console.log(html`<my-transform-script></my-transform-script>`)

context

There are times you will need to pass state to nested child custom elements. To avoid the tedium of passing attributes through multiple levels of nested elements Enhance SSR supplies a context object to add state to.

Parent sets context

export default function MyContextParent({ html, state }) {
  const { attrs, context } = state
  const { message } = attrs
  context.message = message

  return html`
    <slot></slot>
  `
}

Child retrieves state from parent supplied context

export default function MyContextChild({ html, state }) {
  const { context } = state
  const { message } = context
  return html`
    <span>${ message }</span>
  `
}

Authoring

<my-context-parent message="hmmm">
  <div>
    <span>
      <my-context-child></my-context-child>
    </span>
  </div>
</my-context-parent>

instanceID

When rendering custom elements from a single template there are times where you may need to target a specific instance. The instanceID is passed in the state object.

export default function MyInstanceID({ html, state }) {
  const { instanceID='' } = state

  return html`
<p>${instanceID}</p>
  `
}

bodyContent

Enhance SSR outputs an entire valid HTML page but you can pass bodyContent: true to get just the content of the <body> element. This can be useful for when you want to isolate the HTML output to just the Custom Element(s) you are authoring.

const html = enhance({
  bodyContent: true,
  elements: {
    'my-paragraph': MyParagraph,
  }
})
const output = html`
<my-paragraph></my-paragraph>
  `

Integration with <html>, <head>, and <body> elements

Enhance SSR will intelligently merge its rendered <html>, <head>, and <body> elements with any that you provide to it (unless you choose to use the bodyContent: true option).

For example:

const html = enhance({
  elements: {
    'my-content': MyContent,
  }
})

html`
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My Website</title>
  </head>
  <body class="foo bar">
    <my-content></my-content>
  </body>
</html>
`

P.S. Enhance works really well with Begin.

版本与发布记录

@enhance/ssr 共发布 47 个版本,首次发布于 2021/12/11;过去 12 个月发布了 0 个版本。

版本发布日期距今
4.0.3latest2024/07/232 年前
4.0.22024/06/122 年前
4.0.2-next.02024/05/312 年前
4.0.12024/04/172 年前
4.0.02024/04/172 年前
3.5.22024/02/212 年前

关于 @enhance/ssr 的常见问题

@enhance/ssr 是什么?

Server-side rendering for custom elements with template and slots support

如何安装 @enhance/ssr?

在项目目录运行 npm install @enhance/ssr,或使用 pnpm add / yarn add / bun add。

@enhance/ssr 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/enhance__ssr 是否存在。

@enhance/ssr 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@enhance/ssr 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=14.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@enhance/ssr 可以商用吗?

@enhance/ssr 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@enhance/ssr 的下载量有多少?

根据 npm 官方下载统计,@enhance/ssr 在 2026/10/14 – 2026/11/12 这 30 天内被下载 3,135 次,日均约 105 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@enhance/ssr 还在维护吗?

最新版本 4.0.3 发布于 2024/07/23(2 年前);至今共发布 47 个版本,其中过去 12 个月发布了 0 个;首次发布于 2021/12/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。