Feliz: Сделайте Feliz абстрактным API

Созданный на 19 дек. 2020  ·  15Комментарии  ·  Источник: Zaid-Ajaj/Feliz

Я собираюсь предложить критическое изменение, но, надеюсь, такое, которое требует обновлять пакеты только конечных пользователей и авторов библиотеки, а не фактических изменений кода.

  1. F # - отличный язык для объявления пользовательских интерфейсов
  2. Каждый разработчик F #, который делает что-то связанное с Интернетом, пишет свой собственный DSL для объявления пользовательских интерфейсов.
  3. Feliz - отличный API / DSL для объявления веб-интерфейсов React

Что, если мы удалим React из 3? Это могло решить многие проблемы:

  • Фелиз может стать стандартом и решить 2 в списке выше. Таким образом, большинство компонентов, написанных с помощью Feliz, можно было автоматически использовать с различными движками рендеринга.
  • Это также может избежать зависимости Fable.React, как описано в # 285 (Fable.React будет реализовывать IViewElement для сохранения совместимости)
  • Это также может упростить написание серверного рендерера Feliz без необходимости везде использовать #if FABLE_COMPILER как в Fable.React
  • Может случиться так, что кто-то где-то пишет фронтенд-рендерер прямо в Fable. Было бы здорово, если бы он мог просто использовать Feliz

Когда презентация в лифте сделана, если вы считаете, что это хороший ход, мы можем обсудить реализацию. Я еще ничего не пробовал, поэтому не уверен, как это может работать, но я имею в виду примерно следующее:

type IViewElement = interface end
type IViewProp = interface end

// Later renderers can inherit these interfaces
type ReactElement = inherit IViewElement

// The basic renderer interface contains few methods
type IHTML =
    abstract renderNative: tagName: string * props: IViewProp seq

// Most of the helpers would be extensions to the interface
type IHTML with
    member this.div(props: IViewProp seq) = this.renderNative("div", props)
    ...

// Then we have different implementations
module Feliz.React

type ReactHTML() =
    interface IHTML with
        member _.RenderNative(tag, props, children) = ...

let Html = Feliz.ReactHTML()

// Consumer code
open Feliz.React

Html.div [...]

Не уверен, как будет работать intellisense, возможно, нам нужно использовать абстрактный класс вместо интерфейса, но я надеюсь, что вы поняли идею. Что вы думаете?

Самый полезный комментарий

@alfonsogarciacaro Это выглядит потрясающе. Как упоминалось в # 262, единственное, чего мне очень, очень не хватает с тех пор, как я переключился с Fable.React to Feliz, - это SSR «это просто работает». И Feliz, и Feliz.ViewEngine - потрясающие проекты, но наличие двух разных проектов затрудняет повторное использование кода, поскольку любой фрагмент кода, который использует ifdefs, может использоваться только другим кодом, который использует ifdefs - создание разрозненных хранилищ для js-only, dotnet- только и оба-мира-код. Все, что устраняет этот пробел, безусловно, улучшит качество жизни при работе с серверами Feliz и .Net.

Все 15 Комментарий

Привет, @alfonsogarciacaro , честно говоря, я не чувствую, что это хорошая идея. Теоретически это, конечно, имеет смысл: давайте создадим стандартный API для HTML в Fable. На практике это не очень хорошо переводится. Вот пара причин:

  • Текущий API далеко не стандартный, на самом деле он очень самоуверенный. Многим до сих пор не нравится целый список и prop.children , что, конечно, совершенно нормально.
  • Текущий API сделан «простым» из-за предположения, что он предназначен только для React: абстрагирование от него потребует ОЧЕНЬ много работы, где альтернатива написания / дублирования API в стиле Feliz, вероятно, будет более простым решением.
  • Я бы предпочел сосредоточиться на улучшении инструментария для React, чем распылять ресурсы: Feliz далек от завершения, еще многое предстоит сделать в отношении документации, примеров приложений, лучшего опыта тестирования и т. Д.

Большое спасибо за ответ @Zaid! Я понимаю ваши рассуждения, все еще жаль, что у нас так много конкурирующих DSL, но, возможно, есть другие решения, как вы говорите. Если у меня будет время, я все равно попробую написать прототип, чтобы посмотреть, как он будет работать.

Кстати, я начал здесь некоторую работу: https://github.com/alfonsogarciacaro/Feliz.Engine/blob/main/src/HtmlEngine.fs

Я не тестировал его, но я удалил все unbox и подобные трюки, поэтому в принципе он «должен» работать с любым средством визуализации, реализующим этот интерфейс . Было бы неплохо, например, попытаться объединить средство визуализации React с @dbrattli Feliz.ViewEngine и посмотреть, упростит ли это SSR с помощью Feliz.

Есть пара вещей, которые необходимо выяснить / рассмотреть:

Intellisense

Я не очень рад, что мой intellisense будет выглядеть странно, поскольку Html будет определено в Feliz как:

let Html = HtmlEngine(renderer)

Хотя это скорее второстепенная проблема.

Размер связки

Мы, очевидно, хотели бы, чтобы это было таким же, как сейчас (или лучше). Возможно, плагин в Feliz.HtmlEngine , заключенный в директивы компилятора? Однако это решение заставит веб-серверы зависеть от Fable.

Другие библиотеки

Одна из самых больших проблем с SSR, как это делается в настоящее время, заключается в том, что другие библиотеки в большинстве случаев просто не работают, а те, которые работают (например, Feliz.Bulma / Feliz.Bulma.ViewEngine ), по-прежнему нуждаются в корректировках, если они тоже создать абстрактный API, чтобы они могли ссылаться на него, как это есть.

Альтернативы

Я думаю, что основная проблема здесь в том, что пытаться сделать SSR самостоятельно нереально, когда мы хотим полностью имитировать предполагаемую первую отрисовку. Что нам действительно нужно, так это что-то вроде ReactDOMServer для .NET. Я не особо углублялся в это, но будет ли

Большое спасибо за комментарии @Shmew и извиняюсь за поздний ответ:

  • Intellisense : Хм, я написал только простой пример с абстрактным API, но не заметил никаких проблем с автозаполнением. Попробую еще раз проверить. Вместо доступа к статическому типу пользователи обращаются к значению. Думаю, все должно быть хорошо, и во многих случаях код менять не нужно. Основным недостатком, вероятно, будет невозможность использования open type .
  • Размер связки : мне тоже нужно это проверить. Я надеюсь, что это не сильно изменится, потому что члены класса скомпилированы Fable как отдельные функции, которые можно поколебать, а также хорошо минимизировать. Хотя, к сожалению, сгенерированный код будет выглядеть не так красиво, как сейчас после # 284
  • Другие библиотеки : Да, другие библиотеки необходимо адаптировать, чтобы получить преимущества абстрактного API. Надеюсь с минимальными изменениями.
  • Альтернативы : TBH, я действительно не знаю, как работает SSR с React, хотя, глядя на (добавленный) код в Fable.React, он не выглядит очень сложным (в основном просто добавление некоторых метаданных к сгенерированным тегам html), поэтому не уверен проще ли использовать что-то вроде React.NET или нет. Я предполагаю, что этот ootb нельзя будет использовать и с Feliz, так как Feliz содержит трюки Fable (в основном небезопасные приведения), которые будут добавлены в .NET.

На самом деле, для этого я думаю не только о SSR, но и о _beyond React_: wink :, например, для генераторов html на серверах F #, которые не обязательно должны быть совместимы с React, и в случае, если мы хотим использовать другие средства визуализации, кроме Реагируйте на интерфейс.

Большое спасибо за комментарии @Shmew и извините за поздний ответ

Добро пожаловать, не беспокойтесь!

Intellisense: Хм, я написал только простой пример с абстрактным API, но не заметил никаких проблем с автозаполнением. Попробую еще раз проверить. Вместо доступа к статическому типу пользователи обращаются к значению. Думаю, все должно быть хорошо, и во многих случаях код менять не нужно. Основным недостатком, вероятно, будет невозможность использования открытого типа.

Извините, я не совсем понял. Intellisense в порядке, но скорее тот факт, что Html будет другого цвета. Как я уже сказал, действительно второстепенный 😅. Тот факт, что мы теряем возможность open type на самом деле немного важнее. Я знаю, что некоторые действительно предпочитают это, а не все пространство имен.

Размер связки: мне тоже нужно это проверить. Я надеюсь, что это не сильно изменится, потому что члены класса скомпилированы Fable как отдельные функции, которые можно поколебать, а также хорошо минимизировать. Хотя, к сожалению, сгенерированный код будет выглядеть не так красиво, как сейчас после # 284

Я даже не осознавал, что функции взаимодействия еще не были встроены, я уже встроил их в свои библиотеки. Я больше говорил о том факте, что весь модуль Html не имеет увеличения размера пакета по сравнению с тем, если бы это было сделано изначально в JS, потому что это просто встроенная оболочка. С конкретным классом это уже не так.

Другие библиотеки: Да, другие библиотеки необходимо адаптировать, чтобы получить преимущества абстрактного API. Надеюсь с минимальными изменениями.

Проблема заключается в том, что библиотеки, использующие собственный код реакции, не могут работать должным образом, потому что все внутренние компоненты являются только JS.

Альтернативы: TBH, я действительно не знаю, как работает SSR с React, хотя, глядя на (добавленный) код в Fable.React, он не выглядит очень сложным (в основном просто добавление некоторых метаданных в сгенерированные теги html), поэтому не уверен проще ли использовать что-то вроде React.NET или нет. Я предполагаю, что этот ootb нельзя будет использовать и с Feliz, так как Feliz содержит трюки Fable (в основном небезопасные приведения), которые будут добавлены в .NET.

Да, это работает для простых случаев, но если вы попытаетесь использовать более сложные вещи, такие как некоторые компоненты в Feliz.MaterialUI это просто не сработает. Насколько я понимаю, React SSR довольно прост, когда выполняется на node.js, потому что они могут просто запустить ReactDOMServer чтобы фактически выплюнуть полную строку, которая является первой отрисовкой страницы. Насколько я понимаю, React.NET просто обертывает процесс node.js, чтобы сделать именно это.

Я подозреваю, что это было бы довольно просто с кодом Feliz, поскольку он уже поддерживает подобные вещи. Процесс будет примерно таким:

Fable compiles F# React 
-> node.js process imports and returns html string 
-> web server caches output 
-> web server serves page

за пределами React

Это отличный момент, и определенно то, чего я хотел бы, если бы я хотел визуализировать чистый HTML без React или чего-то еще.

Я экспериментировал с этой идеей, вы можете увидеть мой прогресс здесь: https://github.com/alfonsogarciacaro/Feliz.Engine

Еще есть над чем поработать, и у меня есть некоторые сомнения по поводу пары вещей, но он уже работает и охватывает большую часть Feliz API. Однако мне пришлось внести несколько изменений, так что действительно будет сложно заменить Фелиза чем-то вроде этого. Но абстрактная версия Фелиза по-прежнему имеет значение, поскольку она открывает множество возможностей. Некоторые примеры:

  1. Используйте его с другими интерфейсными фреймворками, такими как Sutil: https://github.com/davedawkins/Sutil/pull/15
  2. Используйте его для генерации CSS вместо SASS: https://github.com/alfonsogarciacaro/Feliz.Engine/blob/main/samples/Feliz.Css/Feliz.Css.fs
  3. Используйте его для создания статического HTML: https://github.com/alfonsogarciacaro/Feliz.Engine/blob/main/samples/Feliz.StaticHtml/Feliz.StaticHtml.fs
  4. Используйте его с другой реализацией виртуального дома, например Snabbdom: https://github.com/alfonsogarciacaro/Feliz.Engine/blob/main/samples/Feliz.Snabbdom/Feliz.Snabbdom.fs

Это все черновики, но они работают, и вы можете видеть, что для них требуется очень мало кода. Что еще более важно, все они предлагают пользователям документированный и знакомый API, который также является расширяемым: например, вы можете легко создать BulmaEngine, совместимый со всеми этими (и будущими) приложениями. В случае 2. и 3. Я использую Fable, потому что инкрементная компиляция намного быстрее, чем с .NET, но Feliz.Engine совместим с .NET (я удалил все unbox ), так что это должно быть тривиально. чтобы сделать их совместимыми с серверами F # .NET, и, надеюсь, не потребуется много усилий, чтобы сделать HTML-генератор React-совместимым.

Что ты думаешь, @ Zaid-Ajaj? Я уже отказался от идеи заменить текущий Feliz React API 😅 Но как вы думаете, должно ли что-то подобное принадлежать «семейству Feliz» (может быть, в этом репо)? Вы согласны с названием или хотите использовать что-нибудь другое?

Привет, @alfonsogarciacaro , я глубоко

Привет,

Я очень быстро взглянул на код, и похоже, что эта абстрактная версия будет иметь некоторое влияние на размер пакета. Просто хотел указать на это, так как это была одна из особенностей Фелиза в его нынешнем виде.

Да, влияние ожидается, вопрос в том, насколько оно велико :) Я надеюсь, что для средних и больших приложений это не очень заметно, но, конечно, было бы неплохо иметь что-то вроде fulma-demo в обоих стилях, поэтому мы можно сравнивать и использовать для проверки возможностей оптимизации. Было бы также интересно просто проверить, как встраивание хелперов Feliz влияет на размер пакета. Прямо сейчас код, сгенерированный Feliz, довольно хорош и очень похож на скомпилированный JSX, но функции можно минимизировать, поэтому это может быть способом уменьшить дублирование многих вызовов, таких как .createElement("div") (не уверен, может ли gzip сжимать хотя эти звонки).

Да, я не могу представить, чтобы кто-то был против возможности использовать этот замечательный API / стиль в других проектах. Меня беспокоило только то, повлияет ли это на качество этой библиотеки, и некоторые из эргономических проблем, которые я описал выше.

Привет, @alfonsogarciacaro , я хорошо рассмотрел пример кода. Я был удивлен, увидев, что движок css и движок статического html являются приложениями только для nodejs, поскольку они используют потоки node.js. Хотя идея интересна, мне трудно представить, что я действительно использую что-либо из вышеперечисленного:

  • CssEngine генерирует CSS, в чем преимущество этого по сравнению с использованием только цепочек инструментов CSS / SASS или CSS-in-JS, таких как встроенный в Feliz, или использования других библиотек CSS-in-JS, таких как FSS или Emotion. Создание CSS из F # будет работать само по себе, но это не то, что я бы использовал с Feliz, поскольку использование существующих наборов инструментов было бы лучшим выбором (также более быстрое время компиляции, если вы не хотите, чтобы компилятор Fable / F # замедлялся из-за наличия для компиляции огромных таблиц стилей) В настоящее время я больше предпочитаю использовать модули CSS для компонентов Feliz / React
  • Движок статического HTML: Фелиз уже генерирует статический HTML, используя ReactDOM в узле и в браузере. Feliz.ViewEngine делает то же самое для генерации статического HTML в dotnet. Я знаю, что идея состоит в том, чтобы поделиться API, но это осложняется другими проблемами, как упоминал @Shmew : 3-е библиотеки, которые должны реализовывать оба, влияют на сгенерированный код, который теперь действительно чистый. Он также смешивает атрибуты, стили и дочерние элементы в один список, что нарушает текущий API Feliz.
  • Движок Snabbdom: интересный пример, но не имеет такой экосистемы библиотек, как React.

В общем, интересное упражнение. Честно говоря, я не большой поклонник нового API и лично предпочел бы потратить время на улучшение текущего опыта с большим количеством документов, примеров и привязок в React, вместо того, чтобы пытаться стандартизировать библиотеки. Извините, если я немного негативно отношусь к этому, вы, вероятно, много над этим работали. Я не против иметь то же имя, что и Фелиз, так как оно было вдохновлено библиотекой.

Большое спасибо за проверку образцов @ Zaid-Ajaj! Я ценю вашу честность. Принтеры css и html были просто быстрыми примерами, чтобы проверить, насколько легко / сложно было адаптировать Feliz.Engine к потенциальному использованию (код для печати составляет всего 50 строк). Я использовал Fable & node, потому что инкрементальная компиляция намного быстрее, но «в принципе» ее легко адаптировать к .net. Адаптер Snabbdom должен был стать еще одним быстрым примером, но мне действительно начинает нравиться, хотя это другое дело :)

В любом случае, я наконец понял, что невозможно абстрагироваться от текущих приложений Feliz React, не нарушая изменений (как вы говорили с самого начала 😅), поэтому давайте сохраним его как параллельный проект для пользователей, которые хотят попробовать другие рендеры с API в стиле Фелиза 👍

@alfonsogarciacaro Это выглядит потрясающе. Как упоминалось в # 262, единственное, чего мне очень, очень не хватает с тех пор, как я переключился с Fable.React to Feliz, - это SSR «это просто работает». И Feliz, и Feliz.ViewEngine - потрясающие проекты, но наличие двух разных проектов затрудняет повторное использование кода, поскольку любой фрагмент кода, который использует ifdefs, может использоваться только другим кодом, который использует ifdefs - создание разрозненных хранилищ для js-only, dotnet- только и оба-мира-код. Все, что устраняет этот пробел, безусловно, улучшит качество жизни при работе с серверами Feliz и .Net.

да. это было бы отличным вариантом использования. Хотя это сложно, потому что в конце Feliz.Engine имеет некоторые отличия от Feliz, а это значит, что нам придется написать реализацию Feliz.Engine React, которая будет конкурировать с самим Feliz, чего я бы хотел избежать;) Но, надеюсь, мы сможем найти решение.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

cmeeren picture cmeeren  ·  6Комментарии

Dzoukr picture Dzoukr  ·  9Комментарии

l3m picture l3m  ·  10Комментарии

alfonsogarciacaro picture alfonsogarciacaro  ·  6Комментарии

Zaid-Ajaj picture Zaid-Ajaj  ·  8Комментарии