All streams
Search
Write a publication
Pull to refresh

Comments 13

У меня тоже получилось сделать функциональные компоненты как в Реакте. А затем роутинг и реактивность, уместить на 1 экран кода.

Особо нет времени смотреть на код. Просмотрел только бегло. Сразу возникли вопросы.
1) я вижу, что в примере роуты у Вас через #. Значит ли это, что вы сразу полностью грузите все приложение со всеми страницами? Или это только для примера в codepen?
2) разве в вашем фреймворке (то, от чего я призываю отказаться) можно вставлять теги как есть? Или только через вашу абстракцию?
3) если все-таки нормальные теги (элементы) вставлять можно, то как вы намерены обрабатывать случаи, когда эти элементы исчезают из DOM? Допустим, элемент уничтожен каким-либо способом. Как в таком случае отследить этот момент и очистить обработчик, чтобы ссылка на этот элемент в обработчике не препятствовала работе сборщика мусора?

  1. Роуты в этом примере реализованы на чистом JavaScript, также этот пример одностраничный с использованием внешней зависимости. Но вы можете организовать любую подгрузку страниц на ваш выбор.

  2. Это не фреймворк, а библиотека, которая имеет всего 2 функции, которые делают document.createElement и обновление созданного элемента более простым и декларативным. "Теги" или элементы дерева DOM создаются программно. Есть 3 способа их создания: JSX, fuctional style, hyper style. Вместе с элементами DOM, также добавляются метаданные, чтобы можно было их обновить с помощью функции update(), поэтому элементы можно создавать только функцией создания библиотеки.

  3. Чтобы отследить удаление элемента из DOM - существует пропса mount, в которой можно установить событие на unmount. Более подробный обзор жизненного цикла есть в мануале.

1) а есть реализованный пример нескольких страниц, чтобы можно было увидеть, как там подгружаются скрипты и стили при переходе по ссылкам? Что-то у меня подозрение, что если сделать все по-уму, там будет далеко не один экран..
2) ну.. я бы не сказал, что это прям вот декларативно ) Кроме того, с таким подходом очень резко ограничивается область применения Fusor. Опять же непонятно, чем же это лучше тех же веб-компонентов, если фактически update вызывается императивно.

  1. Есть простой пример роутинга с одноуровневыми переходами и более сложный с многоуровневыми компонентами.

  2. Если update декларируется в пропсе - то декларативно, можно и императивно, либо как в примере в пропсе mount - что тоже декларативно если сделать хэлпер функцию. Кстати не многие осознают что например в Реакт, апдейт также вызывается императивно через - setState().

Напоминает вайб turbolinks.

Вообще, кажется много телодвижений лишние и решаются просто грамотным использованием веб технологий. Тот же FOUC(при внутреннем переходе) решается кешированием стилей. Зачем нужен роутер в такой схеме — не очень понятно. Динамические урл он не поддерживает, стейт между переходами, вроде как, тоже не нужно хранить (у нас же сайт, а не приложение). В общем, не раскрыли тему.

Кстати, интересно что конкретно не получилось сделать с vite. Потому что вообще говоря он для такого должен хорошо подойти.

В целом, желание сделать без фреймворков похвально. Но, ИМХО, гораздо интереснее научиться делать кроссфреймворкные решения. Чтобы был компонент Button и его можно было использовать в react, vue, svelte, или в даже vanilla. И при этом, чтобы было не важно, а на каком фреймворке он написан(или вообще без фреймворка). Кажется это действительно дистилирует подход к вебу и фреймворки станут просто библиотеками.

Кстати, интересно что конкретно не получилось сделать с vite. 

Честно говоря, уже не помню сути... Помню, что там внутренний сервер, который поднимается при разработке, работает совсем не так, как должен работать реальный сервер после деплоя (или как я изначально ожидал).
Вроде еще были проблемы при предобработке html - файлов... Ну а может дело во врожденной кривизне рук )
Насчет необходимости роутера.. Здесь вопрос, конечно, спорный. Я его сделал для возможности разработки именно приложений, в которых есть какое-либо сохраняемое состояние. Динамические роуты - здесь вопрос добавления нескольких регулярок и небольшой доработки. Я не стал с этим заморачиваться по причине отсутствия необходимости.
Ну и js выполняется не мгновенно. До того момента как JS отработает и отрисуются наши веб-компоненты пройдет некоторое время. Поэтому могут быть мигания. Когда же в окне компоненты уже зарегистрированы - такой проблемы нет.


Про проблему с vite, если вспомните, будет интересно почитать поподробнее.

Ну и js выполняется не мгновенно. До того момента как JS отработает и отрисуются наши веб-компоненты пройдет некоторое время. Поэтому могут быть мигания.

А Вы эти мигания на практике наблюдали? Потому что вообще говоря, если делать правильно, их быть не должно.

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

Хм. Не могу придумать подходящий кейс. Обычно на сайтах всё кросстраничное состояние персистентно (либо на сервере, либо в условном localStorage). Можете привести пример состояния, на которое Вы делали расчёт.

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

Тут аккуратнее. Там ещё вопросы приоритетов есть. Вообще, хороший роут матчер — это штука весьма нетривиальная.

Плюс, не очень понятно, как это всё интегрировать с деплоем. То есть сейчас, у Вас initial page load делается в режиме html, няп. И можно просто закинуть весь фронт на cdn и оно просто будет работать. А если появляются динамические роуты, то нужно либо делать какой-то стаб для initial page load (что вредит времени загрузки), либо дублировать роутер в виде конфига для cdn...

Ну и динамические роуты сейчас нужны плюс-минус постоянно. Даже для сайтов. Поэтому важный момент.

P.S. на всякий случай: рассматривали для Ваших задач какой-нибудь Astro, или solid-start?

Ну и динамические роуты сейчас нужны плюс-минус постоянно. Даже для сайтов. Поэтому важный момент.

Логично. Добавил пример. https://grigorenkosergey.github.io/native-SPA/pages/dynamic/12 Правда, реализовал на коленках, может что-то еще упустил.
Может потом внесу UPD в статью.
По приоритетам.. Если высчитывать совпадение с от наиболее специфичного к наименее специфичному, то особых проблем быть не должно.

А Вы эти мигания на практике наблюдали? Потому что вообще говоря, если делать правильно, их быть не должно.

На MDN постоянно вижу, когда перехожу по страницам. Несмотря на то, что там стили и js полностью берутся из кеша.

Хм. Не могу придумать подходящий кейс. 

Ну.. Мне тоже сходу в голову не приходит ) Но я уже говорил об этом, что
"React со своим роутером нанес непоправимый урон моей психике". Потом проведу чуть более полное исследование этого вопроса.

P.S. на всякий случай: рассматривали для Ваших задач какой-нибудь Astro, или solid-start?

Нет. Посмотрю как-нибудь.

Да и забывать о FOUC (Flash Of Unstyled Content) не стоит. Когда страница грузится в первый раз - это не так раздражает, когда это постоянно происходит при перемещениях по страницам одного сайта. Реализовать роутинг в этом случае кажется более простым решением.

Как избежать мелькания нестилизованного контента

До появления Declarative Shadow DOM одним из распространенных методов предотвращения FOUC было применение правила стиля display:none к пользовательским элементам, которые еще не были загружены, поскольку у них не был прикреплен и заполнен их теневой корень. Таким образом, контент не отображается до тех пор, пока он не будет «готов»:

<style>
  x-foo:not(:defined) > * {
    display: none;
  }
</style>

C декларативным теневой DOM

<style>
  x-foo:not(:defined) > template[shadowrootmode] ~ *  {
    display: none;
  }
</style>

На практике ещё если не использовать серверный рендеринг, надо ждать, когда компоненты загрузятся и надо ещё первое отображение обрабатывать, пока роутинг не появится

template.html лучше js файлом сделать.

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

Ну да, как вариант. Только потом TS прикрутить сложно будет без сборщика. Ну и я именно исходные htm/css файлы использовал для того, чтобы автодополнение, которое дает emmet из коробки работало безупречно. Например, такие штуки .parent>.child*5.

Вам не нужен вебпак, Gulp подходит лучше всего для этой задачи. Он и в настройке проще. А со сборкой js отлично справляется esbuild, для стилей sass и тд.

Вообще идея очень интересная, поддерживаю ваше начинание! Считаю велосипеды - это двигатель прогресса. Я тоже устал от Реакта, но пошел немного другим путем. Сделал лоадер для jsx, который позволяет работать с jsx/tsx в node.js, что позволяет получить SSR по умолчанию и без костылей. Своего рода шаблонизатор с jsx синтаксисом и полной поддержкой js внутри. Может выполняться как на сервере, так и на клиенте. Оформил в npm пакет и опубликовал. Готовлю документацию полноценную

Sign up to leave a comment.

Articles