HTM — альтернатива JSX? Или другой вариант?

внешний интерфейс браузер HTML Preact HTM
HTM — альтернатива JSX? Или другой вариант?

HTM — альтернатива JSX? Или другой вариант?

Preact Omi
hyperscript tagged markup demo hyperscript tagged markup demo

Оригинальная ссылка

htmПолное название — Hyperscript Tagged Markup, синтаксис которого похож на JSX.По сравнению с JSX его самые большие преимущества:

  • Компилятор не требуется
  • Работает непосредственно в современных браузерах, если ваш браузер поддерживает это.Tagged templatesпросто хорошо

Таким образом, вы можете использовать его непосредственно в React, Preact или omi и запускать прямо в браузере без какой-либо компиляции. он используетTagged templatesи анализатор HTML, который поставляется с браузером.

очень маленький размер

  • Используйте только 700 байт непосредственно в браузере, менее 1 КБ
  • Используйте только 500 байт в preact
  • При использованииbabel-plugin-htmТребуется только 0 байт

Синтаксис - как у JSX, так и у lit-html

htm вдохновлен lit-html, но включает следующие функции из JSX:

  • Остальные расширения:<div ...${props}>
  • Этикетка самозакрывающаяся:<div />
  • Имя динамического тега:<${tagName}> ( tagNameссылка на элемент)
  • Логическое свойство:<div draggable />

Улучшения JSX

htmДействительно, на основе JSX было сделано множество улучшений, таких как следующие функции, которых нет в JSX:

  • Компилятор не нужен, запускается прямо в браузере
  • Необязательный способ точки с запятой в HTML:<div class=foo>
  • Самозакрытие HTML:<img src=${url}>
  • Необязательный закрывающий тег:<section><h1>this is the whole template!
  • Закрывающий тег компонента:<${Footer}>footer content<//>
  • HTML-комментарии поддерживаются:<div><!-- don't delete this! --></div>
  • Установитьlit-html VSCode extensionподсветка синтаксиса

статус проекта

Первоначальная цель HTM состояла в том, чтобы создать обертку вокруг преиздота, используйте его некомбированным в вашем браузере. Я хочу использовать виртуальный DOM, но я не хочу строить инструменты напрямую модуль ES.

Это означает отказ от JSX, ближайшей альтернативой является [Tagged_templates]. Итак, я написал эту библиотеку, чтобы исправить разницу между ними. Оказывается, этот метод не зависит от фреймворка, поэтому он должен работать с большинством библиотек виртуальных DOM.

Установить

htmОпубликовано в npm, вы также можете посетитьunpkg.comCDN:

npm i htm

Получить его из unpkg:

import htm from 'https://unpkg.com/htm?module'
const html = htm.bind(React.createElement);
// just want htm + preact in a single file? there's a highly-optimized version of that:
import { html, render } from 'https://unpkg.com/htm/preact/standalone.mjs'

руководство пользователя

теперь, когдаhtmявляется универсальной библиотекой, и нам нужно сообщить ей, как «компилировать» наши шаблоны.

Цель должна быть формойh(tag, props, ...children) (hyperscript), и может вернуть что угодно.

// 这是我们的 h 函数。现在,它只返回一个描述对象。
function h(tag, props, ...children) {
  return { tag, props, children };
}

чтобы использовать этоhнам нужно передать привязкуhtmнашимhдля создания собственной функции HTML-тега:

import htm from 'htm';

const html = htm.bind(h);

Теперь у нас естьhtmlТеги шаблона, которые можно использовать для создания объектов в формате, созданном выше, например:

import htm from 'htm';

function h(tag, props, ...children) {
  return { tag, props, children };
}

const html = htm.bind(h);

console.log( html`<h1 id=hello>Hello world!</h1>` );
// {
//   tag: 'h1',
//   props: { id: 'hello' },
//   children: ['Hello world!']
// }

Например

Интересно посмотреть, как все это выглядит? Это рабочее приложение!

Это один файл HTML без сборок или инструментов. Вы можете редактировать его с помощью Nano.

<!DOCTYPE html>
<html lang="en">
  <title>htm Demo</title>
  <script type="module">
    import { html, Component, render } from 'https://unpkg.com/htm/preact/standalone.mjs';

    class App extends Component {
      addTodo() {
        const { todos = [] } = this.state;
        this.setState({ todos: todos.concat(`Item ${todos.length}`) });
      }
      render({ page }, { todos = [] }) {
        return html`
          <div class="app">
            <${Header} name="ToDo's (${page})" />
            <ul>
              ${todos.map(todo => html`
                <li>${todo}</li>
              `)}
            </ul>
            <button onClick=${() => this.addTodo()}>Add Todo</button>
            <${Footer}>footer content here<//>
          </div>
        `;
      }
    }
		  
    const Header = ({ name }) => html`<h1>${name} List</h1>`

    const Footer = props => html`<footer ...${props} />`

    render(html`<${App} page="All" />`, document.body);
  </script>
</html>

ЭтоПредварительная онлайн-версия.

Замечательно? Обратите внимание, что есть только один импорт — здесь мы просто используемimportИнтегрируйте с Preact, так как его легче импортировать и он меньше по размеру.

Тот же пример отлично работает без готовой версии, просто используя два импорта:

import { h, Component, render } from 'preact';
import htm from 'htm';

const html = htm.bind(h);

render(html`<${App} page="All" />`, document.body);

другое использование

потому чтоhtmпредназначен для удовлетворения тех же потребностей, что и JSX, поэтому вы можете использовать его везде, где вы используете JSX.

** использоватьvhtmlСоздать HTML:**

import htm from 'htm';
import vhtml from 'vhtml';

const html = htm.bind(vhtml);

console.log( html`<h1 id=hello>Hello world!</h1>` );
// '<h1 id="hello">Hello world!</h1>'

Webpack configuration via jsxobj: (details here)

import htm from 'htm';
import jsxobj from 'jsxobj';

const html = htm.bind(jsxobj);

console.log(html`
  <webpack watch mode=production>
    <entry path="src/index.js" />
  </webpack>
`);
// {
//   watch: true,
//   mode: 'production',
//   entry: {
//     path: 'src/index.js'
//   }
// }

omi-html

использовать в омиhtm

→ Онлайн-примеры

Usage of omi-html

import { define, render, WeElement } from 'omi'
import 'omi-html'

define('my-counter', class extends WeElement {
  static observe = true

  data = {
    count: 1
  }

  sub = () => {
    this.data.count--
  }

  add = () => {
    this.data.count++
  }

  render() {
    return html`
      <div>
        <button onClick=${this.sub}>-</button>
        <span>${this.data.count}</span>
        <button onClick=${this.add}>+</button>
      </div>`
  }
})

render(html`<my-counter />`, 'body')

запускать прямо в браузере

<script src="https://unpkg.com/omi"></script>
<script src="https://unpkg.com/omi-html"></script>
<script>
  const { define, WeElement, render } = Omi

  define('my-counter', class extends WeElement {

    install() {
      this.constructor.observe = true
      this.data.count = 1
      this.sub = this.sub.bind(this)
      this.add = this.add.bind(this)
    }

    sub() {
      this.data.count--
    }

    add() {
      this.data.count++
    }

    render() {
      return html`
        <div>
          <button onClick=${this.sub}>-</button>
          <span>${this.data.count}</span>
          <button onClick=${this.add}>+</button>
        </div>
        `}
  })

  render(html`<my-counter />`, 'body')
</script>

Star & Fork