Настоящее реактивное программирование в Svelte 3.0

Автор оригинала: Ovie Okeh
  • Перевод

Заголовок статьи может показаться немного кричащим, впрочем как и сам фреймворк Svelte и те идеи, что стоят за ним. Если вы ещё не знаете ничего про Svelte, пристегнитесь, сейчас мы рванём навстречу революции.


Учтите, что это не урок по началу работы со Svelte. Уже существует прекрасное пошаговое интерактивное руководство от команды Svelte, которое погрузит вас в мир реактивного программирования.



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


Хорошо, теперь давайте углубимся в тему!


Но сначала, React


Прежде чем рассказывать, почему я считаю, что Svelte всех порвёт, давайте взглянем на этот недавний твит от человека по имени Dan, и попытаемся понять, что он имел ввиду:



Хм, а почему он тогда называется React?


Ещё одна оговорка: эта статья никоим образом не предназначена для критики React. Я решил использовать его в качестве примера, потому что большинство людей, которые читают эту статью, имели дело с React в тот или иной момент своей жизни. Просто сейчас это лучший пример для противопоставления Svelte.


Что же имел в виду Dan, и как это повлияло на то, как мы сейчас пишем код? Чтобы ответить на эти вопросы, позвольте мне упрощённо рассказать о том, как React работает под капотом.


Когда происходит отрисовка React-приложения, копия DOM помещается в структуру, называемую Virtual DOM. Этот виртуальный DOM выступает посредником между вашим React-кодом и тем, что браузер отображает в DOM.


Затем, при изменении данных (например, после вызова this.setState или useState), React проделывает небольшую работу, чтобы определить, какие части приложения нужно перерисовать.


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


Всё происходит очень быстро, потому что обновлять виртуальной DOM намного дешевле, чем реальный, и React обновляет только необходимые кусочки реального DOM. Эта статья намного лучше объясняет этот процесс.


Вероятно, вы заметили одну особенность. Если вы не сообщите React, что данные изменились (вызвав this.setState или эквивалентный хук), виртуальный DOM не изменится, и от React не последует никакой реакции (та-дам! ).


Вот что имел в виду Dan, когда сказал, что React не полностью реактивен. React полагается на то, что вы самостоятельно отслеживаете данные своего приложения и сообщаете об их изменениях. Это прибавляет вам работы.


Хорошо, теперь про Svelte


Svelte — это совершенно новый способ создавать веб-приложения невероятно быстрым, эффективным и по-настоящему реактивным способом. И всё это без использования виртуального DOM и с меньшим количеством строк кода, чем понадобилось бы в другом фреймворке или библиотеке.


Это всё, конечно, звучит прекрасно, но чем он отличается от множества других JavaScript библиотек и фреймворков? — спросите вы. Я расскажу.


1. Настоящая реактивность


Svelte — это не библиотека. Svelte — это не фреймворк. Скорее, Svelte — это компилятор, который получает ваш код и выдает нативный JavaScript, который напрямую взаимодействует с DOM без необходимости в каком-либо посреднике.


Погоди-погоди, что? Компилятор? Да  — компилятор. И это чертовски хорошая идея, я не могу понять, почему она не была столь очевидной до сих пор. Дальше расскажу, почему я считаю её очень крутой.


Вот цитата из доклада Rich Harris на конференции YGLF 2019:


Svelte 3.0 выносит реактивность из API компонента в сам язык.

Что это означает? Что ж, мы уже знаем, что React (и большинство других фреймворков) требует использовать API, чтобы сообщить ему, об изменении данных (вызов this.setState или useState) и записать их виртуальный DOM.


Необходимость вызова this.setState в React (и иных UI фреймворках и библиотеках) означает, что реактивность вашего приложения теперь привязана к определенному API, без которого оно вообще ничего не будет знать об изменениях в данных.


Svelte использует другой подход.


Его способ исполнения кода был вдохновлён тем, как это сделано в Observable. Вместо обычного запуска кода сверху вниз, он исполняется в топологическом порядке. Посмотрим на фрагмент кода ниже и разберём, что значит — запустить его в топологическом порядке.


1. (() => {
2.   let square = number => number * number;
3.
4.   let secondNumber = square(firstNumber);
5.   let firstNumber = 42;
6.
7.   console.log(secondNumber);
8. })();

При исполнении этого кода сверху вниз, будет показана ошибка в строке №4, потому что для secondNumber используется значение firstNumber, которое на этот момент ещё не было инициализировано.


Если же запустить этот код в топологическом порядке, не будет никаких ошибок. Как так? Компилятор не будет запускать этот код сверху вниз, а рассмотрит все переменные в коде и сгенерирует граф зависимостей(то есть, кто от кого зависит изначально).


Предельно упрощённый путь компилятора, при топологическом прохождении нашего примера, выглядит так:


1. Зависит ли новая переменная 'square' от любой другой переменной?
     - Нет, инициализирую её

2. Зависит ли новая переменная 'secondNumber' от любой другой переменной?
     - Она зависит от 'square' и 'firstNumber'. Я уже инициализировал 'square', но ещё не инициализировал 'firstNumber', что я сейчас и сделаю.

3. Прекрасно, я инициализировал 'firstNumber'. Теперь я могу инициализировать 'secondNumber' используя 'square' и 'firstNumber'
     - Есть ли у меня все переменные, требуемые для запуска выражения 'console.log'?
     - Да, запускаю его.

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


Когда компилятор доходит до строки №4, он обнаруживает, что у него нет firstNumber, поэтому он приостанавливает дальнейшее выполнение и просматривает весь код, в поисках инициализации этой переменной. Что ж, именно это происходит в строке №5, поэтому сначала исполняется строка №5, а затем исполнение кода вернётся к строке №4 и пойдёт далее.


Если кратко: при условии, что выражение A зависит от выражения B, выражение B будет выполняться первым независимо от порядка объявления этих выражений.

Итак, как это соотносится с тем, как Svelte реализует свою настоящую реактивность? Вы можете обозначить любое выражение JavaScript специальной меткой. Это выглядит следующим образом: $: foo = bar. То есть, всё, что нужно сделать, это добавить метку с именем $ перед выражением foo = barstrict mode этого сделать не получится, если foo не была определена ранее).


Так что, когда Svelte видит любое выражение с префиксом $:, он знает, что переменная слева получает свое значение из переменной справа. Теперь у нас есть способ привязки значения одной переменной к значению другой.


Это и есть реактивность! Прямо сейчас мы использовали часть стандартного API самого JavaScript для достижения настоящей реактивности без необходимости возиться со сторонними API типа this.setState.


Вот как это выглядит на практике:


1. // ванильный js
2. let foo = 10;
3. let bar = foo + 10; // bar теперь равен 20
4. foo = bar // bar всё ещё равен 20 (нет реактивности)
5. bar = foo + 10 // теперь bar равен 30

6. // svelte js
7. let foo = 10;
8. $: bar = foo + 10; // bar равен 20
9. foo = 15 // тут bar станет равным 25, потому что зависит от значения foo

Обратите внимание, что в этом примере нам не нужно было заново пересчитывать bar с новым значением foo, ни напрямую, ни повторным исполнением bar = foo + 10, ни путём вызова метода API, вроде this.setState ({bar = foo + 10}). Это делается автоматически.


То есть, когда вы изменяете foo на 15, bar автоматически обновится на 25, и вам не нужно вызывать никакое API, чтобы сделать это. Svelte уже обо всём знает.


Часть скомпилированного Javascript кода, приведенного выше примера, выглядит примерно так:


1. //... 
2. function instance($$self, $$props, $$invalidate) {
3.   let foo = 10; // bar равен 20

4.   $$invalidate('foo', foo = 15) // тут bar станет равным 25, потому что зависит от значения foo

5.   let bar;

6.   $$self.$$.update = ($$dirty = { foo: 1 }) => {
7.     if ($$dirty.foo) { $$invalidate('bar', bar = foo + 10); }
8.   };

9.   return { bar };
10. }
11. //...

Не торопитесь читать дальше, изучите этот фрагмент кода. Не спеша.


Заметили, что обновление значения foo происходит до того, как bar будет объявлен? Это потому, что компилятор анализирует Svelte-код в топологическом порядке, а не построчно сверху вниз.


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


Примечание: В строке №4, значение bar не будет обновлено, пока следующая итерация цикла EventLoop не подчистит все хвосты.


Таким образом, нам больше не нужно заботиться о ручном обновлении состояния при изменении данных. Вы можете весь день думать над логикой приложения, пока Svelte занимается согласованием UI с актуальным стейтом.


2. Краткость


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



17 строк кода против 29


Эти два приложения полностью идентичны по функциональности, но вы можете видеть, сколько кода нам потребовалось написать в React.js —  и даже не просите меня делать это ещё и в Angular .



Я старейший из разработчиков


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


Представьте, что вы только начали изучать веб-разработку. Какой код был бы для вас менее понятен? Тот, что слева, или тот, который справа?


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


Я искренне верю, что такой упрощенный API в Svelte позволит намного быстрее читать и понимать код, улучшая нашу общую продуктивность.


3. Производительность


Хорошо, мы увидели, что Svelte по-настоящему реактивный и позволяет делать больше с меньшими усилиями. Как насчет производительности? И насколько удобны приложения, написанные полностью в Svelte?


Одна из причин, почему React настолько мощный, заключается в том, что он использует виртуальный DOM для возможности перерисовки пользовательского интерфейса приложения небольшими частями, устраняя необходимость перерисовывать весь DOM каждый раз, когда что-то меняется (что действительно очень дорого).


Однако, недостатком этого подхода является то, что в случае изменения данных компонента React будет повторно перерисовывать не только сам компонент, но и все его дочерние элементы независимо от того, менялись они или нет. Вот почему в React существуют такие методы API, как shouldComponentUpdate, useMemo, React.PureComponent и т.д.


Это проблема всегда будет иметь место при использовании виртуального DOM для отрисовки пользовательского интерфейса при изменении состояния приложения.


Svelte не использует виртуальный DOM, но как же тогда он решает проблему перерисовки DOM согласно новым данным состояния? Что ж, позвольте мне снова привести цитату Rich Harris из его замечательного выступления на YGLF:


Фреймворки — это не инструменты организации вашего кода. Это инструменты для организации вашего разума.

Эта мысль привела к идее, что фреймворк может быть чем-то, что работает ещё на этапе сборки приложения, устраняя таким образом необходимость для вашего кода иметь посредника в рантайме. Благодаря этой идее, Svelte стал компилятором, а не фреймворком.


Эта простая идея, также объясняет почему Svelte очень быстрый. Svelte компилирует ваш код в эффективный низкоуровневый Javascript, который напрямую взаимодействует с DOM. Это всё прекрасно, но как Svelte решает проблему перерендеринга всего DOM целиком при изменении данных?


Разница заключается в том, каким образом традиционные фреймворки(например, React) и Svelte узнают, что в состоянии что-то изменилось. Мы уже ранее обсудили, что в React необходимо вызвать метод API, чтобы сообщить ему, когда данные изменяются. В случае Svelte достаточно просто использовать оператор присваивания =.


Если значение переменой состояния  — скажем, foo  — обновляется при помощи оператора =, Svelte, как мы уже знаем, обновит и все другие переменные, которые зависят от foo. Это позволяет Svelte перерисовывать только те части DOM, которые так или иначе получают своё значение из foo.


Я не буду описывать фактическую реализацию этого процесса, потому что эта статья и без того уже достаточно объемная. Но вы можете посмотреть, как сам Rich Harris рассказывает об этом.


В заключение


Svelte 3.0 — одна из лучших вещей, которая появилась в области веб-разработки за последнее время. Некоторые могут назвать это преувеличением, но я не соглашусь. Концепция Svelte и ее реализация позволяют нам создавать большие приложения, при этом отправляя меньше Javascript-кода в браузер пользователя.


Также он позволяет приложениям быть более производительными, более легковесными и при этом получается код, который легче читать. Так сможет ли Svelte заменить в ближайшее время React, Angular или любой другой традиционный UI фреймворк?


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


Подобно тому, как React своим появлением изменил разработку веб-приложений, у Svelte тоже есть потенциал изменить наше представление о фреймворках и возможно, весь процесс мышления при создании приложений.


Счастливого кодинга!


Больше информации о Svelte: Cайт и Telegram

Поделиться публикацией

Похожие публикации

Комментарии 212

    +3
    Я о Svelte узнал от знакомого, посмотрел доку, интересно.
    Но стиль ваших статей вызывает только негативные эмоции.
      +3

      Благодарю за критику, замечу, что это всё же перевод. Вам не нравится сам стиль речи автора и моего перевода, или то, что опять часть статьи посвящена противопоставлению Svelte и React?

        –1

        Думаю стиль автора, но раз вы перевели, то солидарны.
        А сравнение выглядит как jQuery vs React, которое большей частью бессмысленно, разные вещи. Показывайте профит, если он есть, без поливания грязью упоминания "конкурентов" и все ок будет.

          +9

          К сожалению, все кто пытаются рассказывать про Svelte, в той или иной степени опираются на сравнение с традиционными фреймворками. Иначе просто не ответить на вопрос — "А зачем нам ещё один фреймворк?" То, что сравнивают в основном с React, лишь говорит о его популярности и известности. По-моему, заголовок статьи вполне хорошо раскрыт и без излишних оскорблений React в этой области.

            –2
            К сожалению, все кто пытаются рассказывать про <tech_name>, в той или иной степени опираются на сравнение с традиционными <alt_tech_name>.

            Это заблуждение. Ответить на вопрос можно показав результаты бенчмарков или удобство конкретного подхода к задаче. Ну и конечно же рассказав про подводные камни. Без всего этого — это просто публицистика.


            Вот пример статьи которая как раз хорошо рассказывает про технологию и рассказчик достаточно прошарен в ней, чтобы не брать конкретные примеры, а оперировать разными подходами и идеологиями из других языков не прибегая к самим яп: Знакомство с Python для камрадов, переросших «язык A vs. язык B» и другие предрассудки.

              0

              То, кстати, странная статья. По крайней мере, лично я из нее не понял, в чем профит перехода с моих привычных языков.

                +4
                Т.е. вам нужны «бенчмарки» без сравнения с с традиционными <alt_tech_name>. Или в чём заблуждение?
                  0

                  Для меня есть 2 вида статей о технологии:


                  1. A vs B — в таких статьях обязательный бенчмарки и статистика сколько технологии лет, сколько пакетов, какое сообщество. То есть нормальное сравнение. Если тупо бенчей нет => публицистика.
                  2. A only — в таких статьях показывается подход к задаче конкретно с помощью этой технологии. Описываются все плюсы и все минусы. Если начинают приплетать сравнение с другими подходами => публицистика.
                  3. Публицистика — всё как в добрых старых рекламах: "Мы круче всех, но доказывать мы это не будем, потому что можете сами придти и попробовать. А ваш приход в сообщество резко поднимет нам количество людей в сообществе на 100%" Обычно в таких "статейках" начинают оперировать мнимым удобством на спичках при этом вообще не показывая минусов.
                    0

                    Если кратко, то вы не увидели союза "или" в моём высказывании.

          +2
          Сравнение размера кода по количеству строк особенно забавно
          — В React версию добавили div, import и отформатировали по атрибуту на каждой строке. Данные можно хранить как через хуки, так и в state. В чем разница по количеству кода — ну в React надо хендлер явно указать, а там прям какая-то магия связывания. По моему опыту — эти handler — очень малая часть кода.
            +2

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

              +1

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


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

                +2

                Аргументация про реактивное программирование проседает?


                Все ж про более понятный код компонентов Svelte, тут в достаточно утрированном виде, для обывателей рассказано. Можно опять начать спорить, но вся конкретика уже была в упомянутой выше статье и там каждый остался при своём мнении.

                  +1

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

                    +2

                    Я не считаю, что она проседает — поверхностна, да. Но цели углубляться в эту тему в этой статье не было. Для меня структура компонентов Svelte3 сильно лаконичнее и понятнее, чем у любого другого фреймворка. Вот интересно, если бы отписался кто-нибудь, кто не трогал ещё ни Svelte, ни другие топовые фреймворки, со времён JQuery. Какой код ему понятнее?


                    Если хотите прямо фактов — напишите свой канонически верный вариант на React и посчитаем символы, а не строки. Всё равно букв у вас будет больше, как ни старайтесь. Но, что это докажет вам или мне?


                    Прошлые статьи автора были в том числе и про React. Теперь попробовал Svelte. Так что автор не голословен, что-то для себя нашёл в Svelte, раз написал такую длинную статью.

                      0
                      кто не трогал ещё ни Svelte, ни другие топовые фреймворки, со времён JQuery. Какой код ему понятнее?

                      Человеку будет понятен императивный подход без всей этой реактивности. Он ведь ничего кроме jq не видал)

                        +5

                        Я jQuery тоже не видал, да и вообще вебдевом не занимаюсь, а пишу на хаскеле и сиплюсплюс. Так вот, код со Svelte, естественно, понятнее. И приятнее, меньше бойлерплейта.


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

                      0
                      Реактивное программирование в Svelte и без этой статью вызывает вопросы. Вроде и понятно почему так (в JS нельзя узнать, что метод мутирует объект). Но все равно неприятно и можно пропустить. В проде народ что-то типа ImmutableJS использует?
                        +1

                        Насколько я видел, кто работает со Svelte предпочитают решать эту проблему явным присваиванием. Например array.push(3) пишут как array = [...array,3]. Но я не вижу причин, почему бы не использовать ImmutableJS для этого, если кому-то так удобнее.

                          0

                          Потому что в Svelte обновление тригеррится именно по операции присвоения в svelte-компоненте, а присвоение внутри ImmutableJS останется незамеченным?

                            +1

                            Так ведь суть ImmutableJS — что он предлагает неизменяемые объекты? Т.е. все преобразования выдают новый объект, который уже можно присвоить через =.


                            const { Map } = require('immutable');
                            const map1 = Map({ a: 1, b: 2, c: 3 });
                            const map2 = map1.set('b', 50);
                            map1.get('b') + " vs. " + map2.get('b'); // 2 vs. 50
                              0

                              Да, здесь вы правы. Но всё равно стрёмно, что это только в пределах *.svelte сработает, а если отрефакторить и вынести в отдельный файл, то сломается.

                                0

                                Почему вам в таком случае "стрёмен" не сам svelte, а использование ImmutableJS в нём?

                                  0

                                  Да сам Svelte и стрёмен :)

                0
                Убийца реакта? Шо опять?
                  +1

                  Исчезающий убийца реакта

                  –2

                  В js есть прокси, это убирает проблему setState, разработчики не хотели их вводить из за обратной совместимости, почему в Babel нет я уже и не найду. Замена кода на комп лятор в js похожа на золотой унитаз и сводит на снова в дискуссию компиляторы Vs джиты, где как известно победит aot, и окажет мы, что мы говорим о профилях кода. Ну и к вопросу dom, тоже не совсем понятно надо ли, я думаю, что нет. Компиляторы или интерпретатор должен решать проблемы кода а не тулза. Так что выбирая, лучше улучшать последний а не пытаться развернуть поудобней граф исполнения, а в крайности вообще лучше все в васм перевести да и делов

                    –1

                    Почему Svelte постоянно сравнению с React? Я когда вижу в статьях код написанный на Svelte, не сразу отличаю его от Angular и Vue.

                      +1

                      Совсем не так. В прошлой статье было сравнение и с Vue тоже. Да и на Youtube есть пара видео.

                        0
                        Почему автор Svelte не добавляет к сравнению Angular с включенной AOT компиляцией и onPush для всех компонентов (желательно еще с отключенныйми zones, от этого костыля Angular собирается уходить постепенно)?
                          0
                          Думаю по нескольким причинам.

                          Во-первых, Angular играет в другой лиге. Все же это Application Framework, поэтому имеет смысл сравнивать его, например, с Ember. Svelte, React и Vue — это UI фреймворки.

                          Во-вторых, AoT компиляция в Angular работает только для шаблонов. В итоге компоненты все равно зависят от общего Angular core и не являются полностью stand-alone.

                          В-третьих, подобное сравнение уже проводилось, когда только были заявлены прекрасные характеристики Ivy. В итоге, сравнение показало что сравнивать бесполезно.
                            –1
                            В-третьих, подобное сравнение уже проводилось, когда только были заявлены прекрасные характеристики Ivy. В итоге, сравнение показало что сравнивать бесполезно.
                            В одном случае он сравнивает по скорости, а в другом по размеру, это не серьезно. Хотя чего можно было ожидать в свитере кроме троллинга.
                              0
                              Сначала вы недовольны тем, что таких сравнений нет. Потом вам присылают что есть, вы недовольны тем что есть. Если вы лучше представляете как нужно произвести сравнение — сделайте его! Будет интересно, тем более что Ivy и Svelte сильно обновились с того времени.
                        –1
                        Вы это серьезно? Совсем нет разницы?

                        <template>
                          <div>
                            <h1 style="color:red">Hello {{ name }}!</h1>
                            <input v-model="name">
                            <hr>
                        
                            <button v-if="count < 10" @click="count++">
                              Clicks {{ count }}
                            </button>
                            <div v-else>
                              <p>Clicks limit overcome</p>
                              <button @click="count=0">Drop</button>
                            </div>
                          </div>
                        </template>
                        


                        <h1 style="color:red">Hello {{ name }}!</h1>
                        <input [(value)]="name">
                        <hr>
                        
                        <button *ngIf="count < 10; else elseBlock" (click)="count = count + 1">
                          Clicks {{ count }}
                        </button>
                        <ng-template #elseBlock>
                          <p>Clicks limit overcome</p>
                          <button (click)="count=0">Drop</button>
                        </ng-template>
                        


                        <h1 style="color:red">Hello {name}!</h1>
                        <input bind:value={name}>
                        <hr>
                        
                        {#if count < 10}
                          <button on:click={e => count++}>
                            Clicks {count}
                          </button>
                        {:else}
                          <p>Clicks limit overcome</p>
                          <button on:click={e => count=0}>Drop</button>
                        {/if}
                        
                          +1
                          <h1 style="color:red">Hello {{ name }}!</h1>
                          <h1 style="color:red">Hello {{ name }}!</h1>
                          <h1 style="color:red">Hello {name}!</h1>
                          
                          <input v-model="name">
                          <input [(value)]="name">
                          <input bind:value={name}>
                          
                          <button v-if="count < 10" @click="count++">
                          <button *ngIf="count < 10; else elseBlock" (click)="count = count + 1">
                          {#if count < 10} <button on:click={e => count++}>
                          
                          <div v-else>
                          <ng-template #elseBlock>
                          {:else}
                          


                          Для Вас это действительно принципиальная разница?
                            –1
                            Для меня разница очевидна, а что для вас будет разницей тогда?
                              +1

                              Принципиально другой подход, в данном случае просто слегка разные ключевые слова и синтаксис

                                0
                                А давайте говорить конкретно, а не абстрактно? Приведите пожалуйста пример «другого подхода» на примере чего-то реального и существующего?
                                  +1

                                  В давние времена приходилось все делать руками, из js лесть в DOM искать нужный элемент и при изменении состояния менять его или создавать новые элементы. Сейчас все это на себя берут Angular/Vue/React. Вот между этими подходами огромная разница. А разница между тем как написать :if или *ngIf уже не существенна лично для меня

                                    –1
                                    Вы тут говорите о принципе построения веб-приложений, а именно event-based approach и state-based approach. Но изначальный комментарий был именно о характере кода. То что вы не можете отличить React/Vue/Angular/Svelte лишь говорит о том, что опыта использования этих фреймворков у вас не очень много. Я прекрасно вижу как отличия в коде, так и особенности использования.
                                      0
                                      Вы тут говорите о принципе построения веб-приложений, а именно event-based approach и state-based approach

                                      Да, это два принципиально разные подходы, об этом я и говорю, что Svelte никак принципиально не меняет разработку по сравнению с Vue
                                      То что вы не можете отличить React/Vue/Angular/Svelte лишь говорит о том, что опыта использования этих фреймворков у вас не очень много

                                      Я их могу отличить, но когда приходится читать много кода на разных языках, то на такие мелочи перестаешь обращать внимание
                                        0
                                        Да, это два принципиально разные подходы, об этом я и говорю, что Svelte никак принципиально не меняет разработку по сравнению с Vue

                                        Да, все это UI фреймворки основанные на компонентном подходе и state-based моделе управления. Собственно сейчас это практически стандарт для фронтенда.

                                        Я их могу отличить, но когда приходится читать много кода на разных языках, то на такие мелочи перестаешь обращать внимание

                                        Сами писали, что не сразу их отличаете:

                                        когда вижу в статьях код написанный на Svelte, не сразу отличаю его от Angular и Vue.
                                    0

                                    React с его jsx — другой подход.
                                    Knockout, где все запихнули в data-bind — тоже не совсем такой же.
                                    Ещё есть jquery templates, которые выглядят похоже — но основаны не на DOM, а на строковых подстановках со всеми вытекающими особенностями.

                                      –1
                                      Если рассуждать как andreyiq то все это одно и тоже. Вот jquery/mootools — это другой подход, а всякие там ваши ангуляры-реакты — одно и тоже.
                          0

                          А если в процессе работы программы привязка стала не нужна?

                            0
                            Подробнее можете описать задачу?
                              0
                              У меня нет конкретной задачи (точнее, она из другой области — не Web).
                              Если структура проекта (связи между компонентами) — динамические.
                              Сейчас компоненты и связь между ними есть, а через какое-то время — «ведомый» компонент (тот, который получает оповещения об изменении свойств) — удаляется. Или просто — его больше не надо оповещать. Структура проекта изменилась.

                              В скомпилированном проекте такое возможно?
                                0
                                Если компонент уделяется, то все его подписки подчищаются. Это вообще не зависит от компиляции Svelte. Компиляция лишь решает утилитарные задачи и выносит часть вычислений из рантайма.
                            +1
                            Автор специально игнорирует Vue? Он как раз решает эти проблемы React. И он более зрелый и развитый фреймворк.
                              +1

                              Автор не ставил целью сравнить все фреймворки в очередной раз. Автор пытался объяснить механизм работы реактивности в Svelte — что для неё не нужны какие-либо чужеродные конструкции, а только то, что есть в самом Javascript.


                              К слову, я бы с удовольствием почитал статью, где сравнивался бы не Svelte с Vue, а Vue со Svelte, например.

                                +2

                                Как раз требуются: семантика svelte-кода отличается от семантики js-кода. Код обратно несовместим, то есть по сути у нас совсем другой язык. В частности, отличается интерпретация операции присвоения, использования меток и семантика переменных, начинающихся с $.

                                  +1

                                  Вы совершенно правы. Можно назвать это Sveltescrypt. С $ это просто сахар, который легко запомнить и использовать. Но синтаксис сам по себе — всё еще валидный JS, и шаблоны проектирования остаются те же. Хотите переменную стейта — просто пишите let var — как вы делаете для создания обычных переменных Javascript, а не используете "чужеродную конструкцию" для этого.

                                    +2

                                    Нет, не валидный:


                                    import { value } from './store';
                                    
                                    $value = 123;

                                    Это не валидный JS. С точки зрения JS переменной $value в данном контексте не существует. В строгом режиме будет ReferenceError при обращении к необъявленной переменной $value.

                                      +1

                                      JS не валидный, синтаксис валидный.

                                        +2

                                        Ну а какой вообще смысл в валидном синтаксисе, если его семантика всё равно не соответствует общепринятой? Сделали бы тогда уже особый синтаксис, например, <- вместо присвоения и т.п.

                                          0

                                          Скорее всего это сделано, чтобы имеющийся туллинг для Javascript был готов из коробки, например подсветка синтаксиса на Хабре.
                                          Кроме того — реактивные выражения в Svelte — это не обязательно только присваивание. Можно сделать реактивным любое выражение и даже целый блок:


                                          let varA = 0;
                                          $: {
                                              console.log(varA);
                                              console.log(varA*2);
                                          }
                                          // В консоли будут показываться новые значения, всякий раз, когда изменится varA
                                            +4

                                            Ок, вернёмся к нашим баранам. Тулза для JS, например ESLint или IDE, скажет, что $value не определена, а value не используется. Семантика-то другая, да и синтаксически $ теперь уже не часть имени, а оператор. Что толку тогда от такого тулинга?


                                            Более того, в том же Vue, если не ошибаюсь, долгое время были проблемы с тулингом из-за vue-файлов, хотя JS там настоящий. Отсюда возникает и второй вопрос: почему разработчики гуляют по тем же самым граблям?

                                              +1
                                              Отсюда возникает и второй вопрос: почему разработчики гуляют по тем же самым граблям?

                                              Вот это как раз понятно: со встроенным в язык тулингом ничего хитрее Реакта не придумать, а Реакт уже придуман.

                                                –1

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

                                                –1
                                                Ок, вернёмся к нашим баранам.

                                                Ну, не весь имеющийся туллинг же, а по синтаксису. Поэтому для Svelte с первых версий сразу была годная подсветка синтаксиса и притир в любой IDE(особенно, когда компоненты были в *.html файлах ещё). Иначе, в комментариях к статьям про Svelte, только и делали бы, что жаловались на невозможность писать на Svelte где бы то ни было. Сейчас уже экосистема потихоньку обрастает. Есть плагин и для того же ESLint.


                                                Смысл в том, что Svelte — это языки, которые вы уже знаете. HTML, CSS и JS. Т.е. если вы знакомы с этими языками — вы уже знаете 90% Svelte. В каждый из этих языков добавлено немного магии — на изучение которой хватит 15 минут чтения учебника на сайте.

                                                  +3

                                                  А Angular — это HTML, CSS и TS. Всё это исключительно маркетинг.

                                                  +1

                                                  В принципе эта проблема решаема. К примеру для jsx-control-statements есть плагин для eslint. Правда я не уверен, что кто-то делал это для Svelte.

                                                    0

                                                    Конечно решаема, но ведь всё якобы задумывалось, согласно цитате выше, «чтобы имеющийся тулинг для Javascript был готов из коробки». А в результате всё равно получается, что нужны специфичные плагины.

                                                      +2

                                                      Хе-хе, ну есть же динозавры, у которых не линтеров, ни подсветки синтаксиса, ни прочих удобств. У них тулинг "всегда готов" как пионер.


                                                      А если серьёзно, то всегда остаётся какая-нибудь Jet Brains (ну или аналог) со своими парсерами, анализаторами и прочим. Проблема тулинга полноценно решается только для очень крупных игроков (скажем поддержка JSX есть уже в каждой кофемолке). А для несколько менее популярного Vue только пол пути пройдено.


                                                      Вот из недавнего — prettier не умеет в новый pipe-operator в smart виде. Очень удобная штука, но пришлось от неё отказаться :(

                                            0
                                            Вы путаете, там написано было бы:

                                            $: value = 123
                                      –1
                                      Ну вот у вас в первом скрипте уже не валидный JS:
                                      let secondNumber = square(firstNumber);
                                      let firstNumber = 42;


                                      Довольно спорное решение менять сам язык ради фреймворка.
                                    +1
                                    Производительность
                                    Я не буду описывать фактическую реализацию этого процесса, потому что эта статья и без того уже достаточно объемная.

                                    Интересный факт — это самая важная часть, которую можно противопоставлять существующим фреймворкам типа Реакта. Всё остальное (включая синтаксис и кол-во строк кода) — сильно вторично.

                                      +1
                                      Раз для вас это самая важная часть


                                        –1

                                        Супер, спасибо.
                                        Swap Rows прям подозрительно подозрительный. Может потому, что по факту никто не свапит именно строки? Проще на месте одной зарендерить контент второй, и на второй контент первой, не переставляя строки.

                                          0

                                          Нет, я не оправдываю Реакт, но действительно интересно почему такой результат, когда все остальные тесты ± ровно.

                                            0
                                            Просто это синтетические тесты на микрооптимизации, которые не имеют смысла. Поэтому говорим о них только когда спрашивают.
                                              0
                                              синтетические тесты на микрооптимизации

                                              Я думал, речь о принципиально новом подходе, который вы использовали про создании Svelte, а не в микрооптимизациях и другом синтаксисе.


                                              Синтетические тесты имеют смысл для сравнения и именно для этого они и существуют.
                                              Естественно, тест на рендеринг 1000 строк никак не отобразится на реальном проекте с 1000 строк, но даст возможность оценить выигрыш перехода от одной технологии к другой. Поскольку просто так (из-за синтаксиса) никто технологии не меняет. Меняют тогда, когда с используемой технологией возникают сложности (как-то с производительностью и эффективностью используемой памяти). Работая с реактом с проектом в котором десятки тысяч строк и около сотни тысяч дом элементов (да, мы используем переиспользование строк (react-virtualize), но это скорее костыль, чем решение), мне этот вопрос куда более интересен, чем синтаксис.

                                                0
                                                Я думал, речь о принципиально новом подходе, который вы использовали про создании Svelte, а не в микрооптимизациях и другом синтаксисе.

                                                Речь именно о другом подходе, а подобные бенчмарки — это как раз и есть микрооптимизации.

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

                                                Оценивать выигрыш на основе того, что никогда не будет на реальном проекте? Так себе идея.

                                                Поскольку просто так (из-за синтаксиса) никто технологии не меняет. Меняют тогда, когда с используемой технологией возникают сложности (как-то с производительностью и эффективностью используемой памяти).

                                                Именно так.

                                                В целом, как я написал выше — если для вас это важно, бенчмарки всевозможные доступны и вы можете сравнить то, что вас интересует.
                                      +5

                                      Что с TypeScript? Не сыграет ли со Svetle злую шутку то, что Svetle — компилятор? Ведь писать на чистом JS в 2019 году несколько некомфортно, а TypeScript уже чертовски хорош и улучшается семимильными шагами.

                                        0

                                        … я к тому, что в React с TypeScript все замечательно — строгая типизация, вывод типов, GraphQL, поддержка в IDE и т.д.

                                          +1

                                          Что-то на эту тему делается силами сообщества потихоньку.

                                            –1
                                            Ведь писать на чистом JS в 2019 году несколько некомфортн

                                            Многие пишут и им комфортно. Более того, удивляюсь насколько TS популярнее в РФ, чем за рубежом.
                                            +4
                                            > Если вы не сообщите React, что данные изменились (вызвав this.setState или эквивалентный хук), виртуальный DOM не изменится, и от React не последует никакой реакции (та-дам! ).

                                            Тоже самое будет, если не указать $: в Svelte.

                                            > Представьте, что вы только начали изучать веб-разработку. Какой код был бы для вас менее понятен? Тот, что слева, или тот, который справа?

                                            А если не только начали и работаете в команде? Какой код будет более понятен без чтения доп мануалов?

                                            Ну и отсутствие typescript, конечно, огромный минус…
                                              0
                                              Тоже самое будет, если не указать $: в Svelte.

                                              Не совсем то же самое. $: просто назначает следующее за ним выражение быть реактивным — по сути это destiny operator. Кроме него есть ещё переменные стейта let somevar;. Тут вообще ничего не надо делать, чтобы при изменении через присваивание их значения отображались на вьюшке. А this.setState вы обязаны вызывать каждый раз, когда собираетесь изменить данные.


                                              А если не только начали и работаете в команде? Какой код будет более понятен без чтения доп мануалов?

                                              А если команда работает на JQuery, а не на React?

                                                0
                                                А this.setState вы обязаны вызывать каждый раз, когда собираетесь изменить данные.

                                                Тоже самое делает Svelte у себя внутри, только это уже никак не контролируется разработчиком. В React можно четко описывать, когда нужно делать обновление состояния (например, не всегда изменение переменной должно приводить к изменению DOM).
                                                Хотя соглашусь, для простых случаев подход Svelte довольно удобен.

                                                А если команда работает на JQuery, а не на React?

                                                Эммм… и в чем проблема?...JQuery — просто библиотека… подключить ее к React не проблема…
                                                  +2

                                                  Да нет, таки проблема. JQuery — это "просто библиотека" для манипуляций DOM. React — тоже библиотека для манипуляций DOM. Когда две разные библиотеки начинают манипулировать DOM — результат начинает зависеть от мелких деталей их реализации.

                                                    +1
                                                    (например, не всегда изменение переменной должно приводить к изменению DOM).

                                                    А можно конкретный кейс, когда вы не хотите иметь консистентный стейт и его отражение в DOM?
                                                      0
                                                      Дело не в отражении в DOM, а в обновлении элемента в DOM при обновлении его состояния. Как пример, графические элементы, которые интерпретируют диапазоны численных значений — значения постоянно передаются в элемент в виде параметров, но элемент должен обновляться только при определенных их значениях.
                                                      Да и не важны конкретные кейсы — важно наличие возможности управления жизненным циклом элемента.
                                                        0
                                                        Да и не важны конкретные кейсы — важно наличие возможности управления жизненным циклом элемента.

                                                        Не до конца понимаю чем все это отличается от того, как это деалется в React и тем более Vue, где изменение стейта через this.foo также приводит к перерисовке. Давайте говорить конкретно, вы мне пример на React (или чем угодно) и почему вы считаете, что в Svelte нельзя сделать также, а я вам такой же пример на Svelte. Думаю для разработчиков язык кода наиболее доступный и понятный.
                                                          –1
                                                          Посмотрел на lifecycle Svelte — да, есть знакомые методы: onMount, onDestroy, before/afterUpdate. C ходу не увидел метод, аналогичный render в React, но судя по философии Svelte — «A component is a reusable self-contained block of code that encapsulates HTML, CSS and JavaScript that belong together, written into a .svelte file» — он и не нужен.
                                                          Т.е. нельзя в одном файле содержать несколько компонентов или что-то не уловил?

                                                          А пример кода такой (чисто для передачи сути):
                                                          import * as React from 'react'
                                                          
                                                          export type GraphCounterProps = { percent: number}
                                                          export class GraphCounter extends React.Component<GraphCounterProps, {}> {	
                                                          	private _color: string[]
                                                          	constructor(props: GraphCounterProps) {
                                                          		super(props)
                                                          		this._color = ['green', 'yellow', 'red', 'red']
                                                          	}
                                                          
                                                          	shouldComponentUpdate(nextProps: GraphCounterProps) {
                                                          		return (Math.round(this.props.percent / 30) === Math.round(nextProps.percent / 30)) ? false : true
                                                          	}
                                                          
                                                          	render() {
                                                          		return (
                                                          			<span 
                                                          				style={{
                                                          					color: this._color[Math.round(this.props.percent / 30)], 
                                                          					width: 100, 
                                                          					height: 20
                                                          				}}
                                                          			/>
                                                          		)
                                                          	}
                                                          }

                                                            0
                                                            C ходу не увидел метод, аналогичный render в React, но судя по философии Svelte

                                                            Зачем он, если код исполняется один раз, а не перезапускается на каждое изменение стейта?

                                                            Т.е. нельзя в одном файле содержать несколько компонентов или что-то не уловил?

                                                            Конечно нельзя. В реакт тоже нельзя, точнее можно, но за это надо по рукам бить больно.

                                                            А пример кода такой (чисто для передачи сути):


                                                            Тот же пример на Svelte:
                                                            <span style="color: {color}" />
                                                            
                                                            <script>
                                                              let colors = ['green', 'yellow', 'red', 'red'],
                                                                  percent = 0;
                                                            
                                                              $: color = colors[Math.round(percent / 30)];
                                                            
                                                              export { percent };
                                                            </script>
                                                            
                                                            <style>
                                                              span { width: 100px; height: 20px; }
                                                            </style>
                                                            


                                                            Не увидел никаких проблем, лишь ручные оптимизации, которые Реакт заставляет делать разработчиков, а Svelte хендлит сам.

                                                            Сравните во-первых, насколько лаконичнее и декларативнее, во-вторых, насколько меньше действий делается, чтобы осуществить обновление.
                                                              0
                                                              В реакт тоже нельзя, точнее можно, но за это надо по рукам бить больно.

                                                              Глупости. Это скорее напасть Vue с его .vue файлами. React то как раз очень поощряет дробление компонент на минимальные функциональные единицы, настолько маленькие что в здравом рассудке их никто выносить в отдельный файл не будет. Это способствую функциональные компоненты, которые по сути представляют из себя обыкновенную pure-function.

                                                                0
                                                                Правило простое — один компонент, один файл. Лично я выношу даже одну функцию в отдельный файл, если она несет обособленную смысловую нагрузку. У нас есть модули и импорты, нет никаких причин мешать все в кучу, это видимо от большой любви к раннему PHP.

                                                                React поощеряет дробление на мелкие компоненты не от хорошей жизни, а от принципа своей работы — чем меньше функциональная единица, тем меньше работы выполняет Реакт. Иногда это деление настолько не логичное, что потом сидишь и пытаешься «сшить» все эти «лохмотья» в цельное приложение.
                                                                  0
                                                                  Лично я выношу даже одну функцию в отдельный файл, если она несет обособленную смысловую нагрузку

                                                                  У нас есть модули и импорты, нет никаких причин мешать все в кучу, это видимо от большой любви к раннему PHP.

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


                                                                  Но это лирика. По факту же, когда я наблюдаю подход "1 компонент = 1 файл" я вижу вовсе не то, о чём говорят сторонники этого подхода. Никаких чудес не случается.


                                                                  Я вижу длиннющие плохочитаемые плохоподдерживаемые макароны. Это я про Vue. Мне ещё не доводилось встречать примеров кода на Vue которые бы не подходили под это описание. Сколько я не смотрел реальный .vue код это портянки однообразной html-like копипасты в десятки строк. Там где я в React сделал бы 5 компонент в 1 файле с внятным названием и разграничением ответственности vue-воды пишут макароны с копипастой, т.к. подход "1 компонент = 1 файл" этому способствует самым явным образом. В случае использования какого-нибудь material-ui или другой многословной UI либы уровень мусора достигает немыслимых размеров.


                                                                  Причина этому банальна. Если выносить все мелкие парустрочные сущности, обёртки, группировки и пр. в отдельные файлы, то те самые общие импорты и экспорты начинают занимать большую часть кодовой базы. В добавок к этому с огромным количеством крошечных файлов состоящих почти целиком из бойлерплейта работать гораздо менее удобно, чем с в 3-4-5 раз меньшим количеством файлов по 20-40 строк.


                                                                  чем меньше функциональная единица, тем меньше работы выполняет Реакт

                                                                  Обычно чем больше вы дробите, тем медленнее работает приложение. Как минимум начиная с какого-то уровня. Одна из самых странных и нелепых оптимизаций приложений заключается как раз в том, чтобы компоненты инлайнить ({comp(props)}, вместо <Comp {...props}/>). И это правда помогает (чуть-чуть).


                                                                  То о чём вы говорите это уровень хаоса, когда человек все гребёт в один компонент явно нарушая принцип ограниченной ответственности. Но это дет сад :)

                                                                    0
                                                                    Но это лирика. По факту же, когда я наблюдаю подход «1 компонент = 1 файл» я вижу вовсе не то, о чём говорят сторонники этого подхода. Никаких чудес не случается.

                                                                    Не повезло вам. Лично я не видел хорошо написанных React компонентов)

                                                                    Причина этому банальна. Если выносить все мелкие парустрочные сущности, обёртки, группировки и пр. в отдельные файлы, то те самые общие импорты и экспорты начинают занимать большую часть кодовой базы.

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

                                                                    Обычно чем больше вы дробите, тем медленнее работает приложение. Как минимум начиная с какого-то уровня.

                                                                    В реакт отсечкой для рендеринга vdom является компонент. Так как иных способов ограничить rerender/reconcile внутри не существует, в реакт вы вынуждены дробить приложение на максимально мелкие кусочки, которые как вы верно выразились, ухудшают поддержку и читабильность. Но еще хуже, когда эти мелкие кусочки сваливаются в один файл. Это финал вообще.

                                                                    То о чём вы говорите это уровень хаоса, когда человек все гребёт в один компонент явно нарушая принцип ограниченной ответственности. Но это дет сад :)

                                                                    Грести в один компонент не надо. Также как грести несколько компонентов в один файл. Компоненты должны иметь смысл, а 1-2х строчные компоненты редко имеют смысл, кроме отсечки рендеринга. Компоненты как раз и нужно разделять согласно single responsobility. Если никакой responsobility нет вообще, если компонент — это просто кусок шаблона, то и смысл в таких компонентах? Раньше это вообще называлось partial и даже не было полноценным шаблоном.
                                                                      –1

                                                                      Я понял вашу мысль. В корне с ней не согласен. Вот прямо по всем пунктам. Но спорить не буду. Я только уточню, 1-2 строчные функции тоже зло? Если да, то и правда финиш, если же нет, то осталось только понять отчего вы считаете, что компоненты и функции чем-то серьёзно отличаются друг от друга.

                                                                        –1
                                                                        Я понял вашу мысль. В корне с ней не согласен. Вот прямо по всем пунктам. Но спорить не буду.

                                                                        Право ваше и спор тут не поможет конечно.

                                                                        Я только уточню, 1-2 строчные функции тоже зло?

                                                                        Функции это про функции, компоненты — это больше про классы. То что в Реакт компоненты прекратили в функции — это не очень здоровая идея.

                                                                        Если да, то и правда финиш, если же нет, то осталось только понять отчего вы считаете, что компоненты и функции чем-то серьёзно отличаются друг от друга.

                                                                        Потому что функция — это то, что вызывается с аргументами и возвращает результат, каждый раз исполняя логику внутри. Компонент — это то, что инкапсулирует стейт, логику работы с ним, а также может инстанциироваться множество раз. То есть это больше похоже на класс. Именно от того что в Реакт компоненты вдруг стали функциями и ростут все проблемы с производительностью, когда все содержимое компонента вынуждено инициализироваться каждый раз на каждое изменение входных данных. Это просто с точки зрения понимания, но совершенно не эффективно. Именно поэтому в Реакт есть костыли вроде useMemo, useCallback, useReducer, React.PureComponent, shouldComponentUpdate и так далее.

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

                                                                        Кроме того, я даже физически не могу представить себе компонент из 2-х строчек в Svelte. В Реакт могу, потому что он неполноценных феймворк, без работы со стилями. Например, если представить что у нас есть компонент ссылки:

                                                                        <a {href} {title} class="link">{text}</a>
                                                                        


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

                                                                        <a {href} {title} class="link">{text}</a>
                                                                        
                                                                        <style>
                                                                          a { color: red; }
                                                                          a:focus { outline: 2px solid red; }
                                                                        </style>
                                                                        

                                                                        И вот он уже не однострочный и требует отдельного файла.
                                                                          +1
                                                                          То что в Реакт компоненты прекратили в функции — это не очень здоровая идея.

                                                                          Возможно. Тут есть о чём поспорить. Но именно в этом и заключается react-way.


                                                                          Компонент — это то, что инкапсулирует стейт, логику работы с ним, а также может инстанциироваться множество раз.

                                                                          Редкий компонент stateful. Почти все как раз stateless. Ну если писать идеоматично.


                                                                          Именно поэтому в Реакт есть костыли вроде useMemo, useCallback, useReducer, React.PureComponent, shouldComponentUpdate и так далее.

                                                                          С этим трудно спорить. Тут много подводных камней, неочевидных моментов. И мало кто в это умеет. Но к нашему разговору это пожалуй имеет ровным счётом никакого отношения.


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

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


                                                                          И вот он уже не однострочный и требует отдельного файла.

                                                                          Не требует :) Если вышестоящий компонент состоит из 3-4 включений подобных однострочных под-компонент, то размазав их по файловой системе, вы только усложните жизнь тому, кто будет их поддерживать.


                                                                          По сути говоря тут вопрос между: 5 файлами крошечного размера и 1 файлом в 10-30 строк. Работать со вторым гораздо удобнее. Что и показывает реальная практика Vue. Вместо того чтобы выносить подобные вещи в отдельные компоненты они всё инлайнят как есть в вышестоящий компонент и получают лапшу.


                                                                          И вот в этом мне как раз симпатизирует React-way. Всё есть функция. Функции с телом больше 5 строк — это хороший повод задуматься о разделении её на несколько. Такая же картинка и с компонентами, ибо они тоже функции с чётко заданной ролью.


                                                                          Писать таким во Vue пока нельзя :( Точнее можно, это это сильно против шерсти. С третьей версии обещают ввести. Посмотрим во что это выльется.


                                                                          В спор касательно природы реактивности Svetle вступать не хочу, т.к. довольно долго работал с Knockout и знаю, что всё не так просто и радужно, как кажется на первый взгляд.

                                                                            +1
                                                                            Возможно. Тут есть о чём поспорить. Но именно в этом и заключается react-way.

                                                                            Ок, react-way, это мне понятно. Можно тогда сказать, что полноценные однофайловые компоненты, которых нет в реакт, это svelte-way. Необязательно только присовывать react-way повсюду, как это любят делать адепты этого замечательного фреймворка.

                                                                            Редкий компонент stateful. Почти все как раз stateless. Ну если писать идеоматично.

                                                                            Наоборот, редкий компонент stateless, чаще всего все же stateful. А если он все же stateless, то обычно это так называемые leaf-компоненты или dumb-компоненты, как это любят называть в реакте. Правда если уж у них вообще нет стейта, то такие компоненты даже компонентами назвать сложно. Это скорее шаблоны или partials, если совсем ко класике. Просто у современных фреймворков нет иных выразительных средств, поэтому все лепят компонентами. Но вот есть например lit-html:

                                                                            const template = data => html`
                                                                              <h1>Hello ${data.title}</h1>
                                                                              <p>Hello ${data.description}</p>
                                                                            `;
                                                                            
                                                                            render(template(state), document.body);
                                                                            

                                                                            Один в один реакт на функциях ведь, только нативный абсолютно. И вот незадача, ни у кого язык не поворачивается это гордо называть компонентом. Шаблон это.

                                                                            С этим трудно спорить. Тут много подводных камней, неочевидных моментов. И мало кто в это умеет. Но к нашему разговору это пожалуй имеет ровным счётом никакого отношения.

                                                                            Имеет, так как ноги ростут в том числе из функциональных компонентов. А смешивание их в один файл лишь добавляет «подводных камней» и «неочевидных моментов».

                                                                            Очень спорный момент. У меня почти все компоненты не имеют собственных стилей.

                                                                            Значит у вас не совсем полноценные и плохо переносимые компоненты. Я еще понимаю когда люди сверху крутят всякие styled-components (хоть это и адуха).

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

                                                                            Если нужно, можно и глобальные стили юзать. Это ухудшает переиспользуемость и переносимость, но совершенно не мешает подходу с компонентыми стилями. Даже используя ShadowDOM можно позволить внешним стилям работать внутри компонента.

                                                                            Это избавляет от необходимости писать стили повсеместно и тем более их дублировать. Но сейчас так не модно, да.

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

                                                                            Не требует :) Если вышестоящий компонент состоит из 3-4 включений подобных однострочных под-компонент,

                                                                            Я же написал вам пример компонента. Он уже не однострочный, а ведь там еще 20 строк стилей. Да и разметка наврядли такая простая. Вы предлагаете все эти 3-4 20-ти строчных компонента помещать в тот же файл, что и вышестоящий компонент? Чудно как-то.

                                                                            Да, я понял, что вы пишете компоненты без стилей. Только исходя из того, что я написал выше, это либо не компоненты вовсе, а шаблоны или partials. Либо это какие-то недоделанные компоненты.

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

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

                                                                            По сути говоря тут вопрос между: 5 файлами крошечного размера и 1 файлом в 10-30 строк.

                                                                            Если бы вы писали полноценные компоненты, то у вас не было бы 1-2 строчных компонентов просто по определению. А значит один общий файл был бы не 10-30 строк на 5 компонентов, а уже 100-150 строк.

                                                                            Работать со вторым гораздо удобнее. Что и показывает реальная практика Vue.

                                                                            У нас реальная практика Vue с выхода 2-й версии и это не так. SFC — это лучшее что есть во Vue и всегда было.

                                                                            Вместо того чтобы выносить подобные вещи в отдельные компоненты они всё инлайнят как есть в вышестоящий компонент и получают лапшу.

                                                                            Так делают видимо те, кто пришел с реакт и любит лапшу. За это тоже надо бить по рукам. Благо Svelte изначально уберегает от этого.

                                                                            И вот в этом мне как раз симпатизирует React-way. Всё есть функция. Функции с телом больше 5 строк — это хороший повод задуматься о разделении её на несколько. Такая же картинка и с компонентами, ибо они тоже функции с чётко заданной ролью.

                                                                            То есть если у вас чисто HTML-макет больше 5-ти строк на одну логическую единицу, то вы ее все равно дробите на компоненты? Странно, обычно стейт компонента около 5-и строк занимает, плюс всякие там JSX примочки типа обязательного рут-элемента (+2 строчки). Ну-ка я попробую:

                                                                            function Component(props) {
                                                                              return <>
                                                                                <h1>Hello ${props.title}</h1>
                                                                                <p>Hello ${props.description}</p>
                                                                              </>;
                                                                            }
                                                                            

                                                                            Хм, уже 4 строки. Получается еще одна и надо на дополнительный компонент делить?

                                                                            Писать таким во Vue пока нельзя :( Точнее можно, это это сильно против шерсти. С третьей версии обещают ввести. Посмотрим во что это выльется.

                                                                            Да, ох уж эти китайцы. Понахватают всего дурного и тянут в рот…

                                                                            В спор касательно природы реактивности Svetle вступать не хочу, т.к. довольно долго работал с Knockout и знаю, что всё не так просто и радужно, как кажется на первый взгляд.

                                                                            Насколько я знаю реактивность в Knockout реализована с помощью observerables, а в Svelte с помощью компиляции и топологического порядка исполнения. Какая связь в таком случае?
                                                                              0

                                                                              Судя по всему самые большие у нас с вами разногласия касаются стилей (да и бог с ними), и терминов (patrials, templates, ...). Чтобы не путать вас дальше, буду стараться использовать вашу терминологию.


                                                                              Вот согласной вашей терминологии во Vue мне не хватает этих самых partials, чтобы избегать излишней лапши и дробить эти здоровенные куски html на внятные именованные параметризированные блоки, без создания груды лишних файлов. То что они будут stateless меня нисколько не смущает. Меня смущает сам факт того, что я не понимаю как это сделать. Вероятно я что-то упустил в документации.


                                                                              Отсюда вопрос, раз уж вы упомняли, что у вас позитивный опыт с Vue и SCF, что там с partials? Беглый поиск меня привёл к тому, что до 0.12 там они и правда были. Как эту проблему решают теперь?


                                                                              У меня нет никаких претензий к подходу "1 файл = 1 компонент", при удовлетворении двух пунктов: поддержка именованных переиспольуземыех параметризированных stateless блоков (partials?), вашей формулировки того что такое компонент. Наличие двух stateful компонент в одном файле и в React я считаю антипаттерном.


                                                                              Теперь касательно спора Svelte vs React. Я не готов тут спорить, т.к. о Svelte я знаю чуть больше, чем ничего. Пара статей и видео презентация. Ваш аргумент про то, что это не observable вполне справедлив, ошибочка вышла, sorry.

                                                                                0
                                                                                Вот согласной вашей терминологии во Vue мне не хватает этих самых partials, чтобы избегать излишней лапши и дробить эти здоровенные куски html на внятные именованные параметризированные блоки, без создания груды лишних файлов. То что они будут stateless меня нисколько не смущает. Меня смущает сам факт того, что я не понимаю как это сделать. Вероятно я что-то упустил в документации.

                                                                                Думаю способ это сделать по-другому делить приложение на компоненты. Потому что например у нас такой проблемы просто нет или она просто настолько редкая, что я не могу вспомнить. Может пример есть какой-то?

                                                                                Отсюда вопрос, раз уж вы упомняли, что у вас позитивный опыт с Vue и SCF, что там с partials? Беглый поиск меня привёл к тому, что до 0.12 там они и правда были. Как эту проблему решают теперь?

                                                                                Самое интересное что их оттуда выпилили на хайпе вокруг Реакт. Типа все в вашем приложении это компонент. А ведь изначально Vue их подрезал, как и все остальное, у Ractive (прямого предка Svelte). Но мода на только лишь компоненты лишила большую часть фреймворков дополнительных выразительных средств.

                                                                                Наличие двух stateful компонент в одном файле и в React я считаю антипаттерном.

                                                                                Ок, тут мы сошлись. Тогда может попробуем какой-то пример разобрать. Глядишь я с вами и соглашусь.

                                                                                Ваш аргумент про то, что это не observable вполне справедлив, ошибочка вышла, sorry.

                                                                                Принято.

                                                                                  0
                                                                                  Может пример есть какой-то?

                                                                                  Например вот такой компонент. Взял первое что под руку подвернулось. Груда html. Много-много разметки. По разметке разбросано много-много относящихся только к UI аттрибутов. В итоге код на много экранов. Стейт значение всего 1.


                                                                                  Что можно сделать даже не вникая в код? Ну разбить эти куски на отдельные "partials" с внятными именами. И тогда получаем иерархическую структуру где каждое звено лаконично и удобочитаемо. Когда частности не мешают читать целостную картинку и при этом доступны под рукой.


                                                                                  Как такое сделать во Vue? Создать 10 файлов?

                                                                                    0

                                                                                    Конкретно в вашем файле я вижу лишь один компонент и один фрагмент (drawer), повторяющийся аж два раза.


                                                                                    Его можно вынести в отдельный файл или повторить два раза, это принципиально в подобном коде ничего не изменит.

                                                                                      0

                                                                                      С 86 по 164 строку мы видим груду html-like лапши. Которую тяжело читать и с ней тяжело работать. Сколько раз там дублируется drawer значения не имеет. Вместо эти 80 строк визуального мусора я ожидаю увидеть суть. А нюансы (груды аттрибутов и всякие обёртки) можно вынести на следующий уровень иерархии (partials)?


                                                                                      В конце концов мы же не пишем так обыкновенный код. А компоненты так пишут. В случае Vue особенно часто их пишут именно так (но искать пример для вью мне было лень).


                                                                                      В рамках терминологии PaulMaly вся эта лапша должна быть единым компонентом, т.к. компонент должен быть stateFul. Дескать нельзя выносить stateLess части в отдельные компоненты.


                                                                                      Решение — выносим все эти части в stateLess "partials" и тогда код <ResponsiveDrawer/> становится легко-читаемым и с ним становится удобно работать. Проблема — partials из Vue выпилили.

                                                                                        0

                                                                                        Почему вы "ожидаете увидеть суть" в Svelte, но при этом миритесь с "визуальным мусором" в React?

                                                                                          0
                                                                                          но при этом миритесь с "визуальным мусором" в React?

                                                                                          Не понял, о чём вы. Приведённый выше пример кода — пример html-like лапши. Не надо так писать :) Really. Не надо с этим "мириться". React позволяет писать по-другому.


                                                                                          Про Svelte я кстати не писал. Вполне вероятно что там есть "partials" и такая проблема не стоит вообще. Это во Vue их нет.

                                                                                          0
                                                                                          В рамках терминологии PaulMaly вся эта лапша должна быть единым компонентом, т.к. компонент должен быть stateFul. Дескать нельзя выносить stateLess части в отдельные компоненты.

                                                                                          Не не, это я вашу терминологию натягивать с подхода «все есть компонент», а более правильную, «не все есть компонент, а что еще и шаблон/partial». Мое же решение вашей проблемы — это иной подход к декомпозиции компонентов в принципе.
                                                                                        0
                                                                                        Как я и написал выше, нужно просто по-другому сделать декомпозицию приложения. Глядя на ваш файл, сразу видно, что сделать что-то не так с этим. Почему у этого компонента одновременно отрисовывается appbar, navbar и контент? Это что компонент страницы? А в названии почему-то будто это компонент Drawer.

                                                                                        Я бы декомпозировал примерно так, если сходу:

                                                                                        <div class="root">
                                                                                          <BasicAppBar 
                                                                                            title="Responsive drawer" 
                                                                                            on:click={e => open = !open}
                                                                                          />
                                                                                        
                                                                                          <EmailDrawer {open} />
                                                                                        
                                                                                          <main>
                                                                                            <svelte:component this={Content} />
                                                                                          </main>
                                                                                        </div>
                                                                                        
                                                                                        <script>
                                                                                          export let open = false,
                                                                                                    Content = null;
                                                                                        </script>
                                                                                        
                                                                                        <style>
                                                                                          .root { ... }
                                                                                          main { ... }
                                                                                        </style>
                                                                                        


                                                                                        Правда ведь компонент страницы стал выглядить и читаться значительно проще?
                                                                                          0

                                                                                          Но теперь у вас это "компоненты", хотя они и stateLess. И как бы вы не дробили, вы дойдёте до:


                                                                                          <IconButton
                                                                                              color="inherit"
                                                                                              aria-label="Open drawer"
                                                                                              edge="start"
                                                                                              onClick={handleDrawerToggle}
                                                                                              className={classes.menuButton}
                                                                                          >
                                                                                              <MenuIcon />
                                                                                          </IconButton>

                                                                                          По-хорошему такое надо вынести в отдельный компонент. Но ведь оно же stateLess. Вы выше писали:


                                                                                          А если он все же stateless, то обычно это так называемые leaf-компоненты или dumb-компоненты, как это любят называть в реакте. Правда если уж у них вообще нет стейта, то такие компоненты даже компонентами назвать сложно. Это скорее шаблоны или partials, если совсем ко класике.

                                                                                          И мы снова вернулись к partials. В примере выше практически все эти 80 строк это stateLess.


                                                                                          Всякие там -aria аттрибуты, разметка og:graph, нюансы вёрстки часто вынуждают писать груды объёмного stateless html.


                                                                                          И в случае Vue я вижу что народ не парится и всё постит в 1 файл с тонной подобного мусорного кода. Приходится сильно много парсить глазами, чтобы понять что тут почём. И важные вещи вроде -v директив теряются в этой горе мусора.


                                                                                          В partials их не вынести, за их отсутствием. В отдельные файлы тащить каждый такой нюанс — сильно усложнить жизнь в поддержке (такое по 100 раз на дню переделается, с грудой крошечных файлов работать неуодобно, git очень плохо умеет в переименовывание и "наследование" файлов, постоянная проблема с именованием, тонны импортов и экспортов, особенно дублирование общих зависимостей, и т.д.). Добавить к этому что даже vsCode для js всё ещё космически далёк от уровня полноценных IDE для статически типизированных языков и мы получаем боль.


                                                                                          В итоге пока я писал на вью (очень непродолжительное время, vue разочаровал меня не только в этом) я перешёл на string-templates в js файлах. Вместо "partials" писал компоненты которые явным образом приходилось ставить в components: { UserPanelHeader, ... }. Вскоре я выяснил что разработка за пределами .vue файлов это вообще не vue-way и никто всерьёз её поддержкой заниматься не хочет.

                                                                                            0
                                                                                            Похоже вы меня немного не верно поняли. Бывает.

                                                                                            Но теперь у вас это «компоненты», хотя они и stateLess. И как бы вы не дробили, вы дойдёте до:

                                                                                            Конечно дойду, это и будут те самые leaf-компоненты. Которые кстати тоже далеко не всегда полностью stateless, скорее их дучше назвать dumb или pure, в том смысле что результат их работы зависит от пропсов, без особой внутренней кухни.

                                                                                            И мы снова вернулись к partials. В примере выше практически все эти 80 строк это stateLess.


                                                                                            Нет не вернулись. Мы все еще говорим о том, что если композиция произведена верно, никаких 1-2 строчных недокомпонентов быть не должно. Также как не должно быть таких вот монстров из вашего примера.

                                                                                            Чтобы было понятно дальше, в своих проектах на Svelte делим компоненты на 3 вида: components (leaf/dumb/pure компоненты, переиспользуемые и переносимые), views (компоненты реализующие конкретную логическую единицу приложения, smart, не переносимые обычно), layouts (компоненты лейаутов).

                                                                                            Так вот компоненты IconButton, List, Divider, ListItem — это все компоненты. Компоненты BasicAppBar, EmailDrawer — это вьюхи, которые внутри юзают компоненты и другие вьюхи, и содержат логику этой части приложения. Ну а компонент из моего примера — это лейаут. Все четко и по полкам, никаких 1-2 строчных компонентов, никаких огромных кусков html.

                                                                                            И в случае Vue я вижу что народ не парится и всё постит в 1 файл с тонной подобного мусорного кода. Приходится сильно много парсить глазами, чтобы понять что тут почём. И важные вещи вроде -v директив теряются в этой горе мусора.

                                                                                            Далеко не все так делают, вам видимо не везло.

                                                                                            В итоге пока я писал на вью (очень непродолжительное время, vue разочаровал меня не только в этом) я перешёл на string-templates в js файлах.

                                                                                            Есть подозрение что вы пришли туда уже после опыта с React и декомпозировали приложение схожим для него образом. Но во Vue и Svelte надо делать не так.

                                                                                            Вскоре я выяснил что разработка за пределами .vue файлов это вообще не vue-way и никто всерьёз её поддержкой заниматься не хочет.

                                                                                            Да, Vue как бы поддерживает и классы, а-ля ангуляр и из реакт с JSX, но в основном все пишут SFC, потому что это удобно.
                                                                                              0

                                                                                              Ок, пускай это будет leaf-component. Тогда моя позиция проста: я не вижу смысла выносить мелкие однообразные leaf-компоненты в отдельные файлы, т.к. с такой разбухшей кодовой базой мне становится слишком тяжело работать. Почему? Выше в крадце описал. А других альтернатив декомпозиции Vue мне не предоставляет.


                                                                                              И мне пока не попадалось на глаза кодовой базы, где был бы вынос leaves в отдельные файлы. В лучшем случае так.


                                                                                              Не исключено, что в хороших компаниях именно так и пишут. Было бы интересно посмотреть.

                                                                                                0
                                                                                                <template>
                                                                                                  <div class="md-table-pagination">
                                                                                                    <template v-if="mdPageOptions !== false">
                                                                                                      <span class="md-table-pagination-label">{{ mdLabel }}</span>
                                                                                                
                                                                                                      <select-page-size 
                                                                                                        v-model="currentPageSize" 
                                                                                                        @changed="setPageSize"
                                                                                                        pageOptions="mdPageOptions"
                                                                                                      <md-field>
                                                                                                
                                                                                                    </template>
                                                                                                
                                                                                                    <span>{{ currentItemCount }}-{{ currentPageCount }} {{ mdSeparator }} {{ mdTotal }}</span>
                                                                                                
                                                                                                    <prev-button @click="goToPrevious()" :disabled="mdPage === 1"/>
                                                                                                    <next-button @click="goToNext()"/>
                                                                                                  </div>
                                                                                                </template>

                                                                                                Примерно об этом говорю. Вынос prev-button, next-button, select-page-size из основного тела шаблона, куда-нибудь рядом. Чтобы и идти недалеко на "нюансами", и не разбухал основной шаблон.

                                                                                                  0
                                                                                                  Так сделайте для них общий компонент кнопки как частный случай кнопки с иконкой. Он скорее всего еще где-то пригодится:

                                                                                                  <md-button class="md-icon-button {classes}" {disabled} on:click>
                                                                                                    <md-icon>{icon}</md-icon>
                                                                                                  </md-button>
                                                                                                  
                                                                                                  <script>
                                                                                                    export let icon = '',
                                                                                                               disabled = false,
                                                                                                               classes = '';
                                                                                                  </script>
                                                                                                  

                                                                                                  И юзайте:

                                                                                                  <IconButton 
                                                                                                    icon="keyboard_arrow_left"
                                                                                                    on:click={goToPrevious} 
                                                                                                    disabled={mdPage === 1} 
                                                                                                  />
                                                                                                  <IconButton 
                                                                                                    icon="keyboard_arrow_right" 
                                                                                                    on:click={goToNext} 
                                                                                                  />
                                                                                                  
                                                                                                    0

                                                                                                    Там где игра действительно стоила свеч (какие-нибудь универсальные переиспользуемые UI обёртки) — я так и делал. Но таких мест было довольно мало. Чаще всего куски были более-менее уникальными.


                                                                                                    Честно говоря мне надоело спорить :( Мы переливаем из пустого в порожнее без всякого на то смысла. Суть: мне паталогически не хватает partials во Vue. На мой вкус и цвет SCF в нём это зло ровно до тех пор, пока "именованные параметризированные stateless блоки" туда не вернут. А до тех пор я считаю что такой подход приводит к в той или иной степени разбухшему говнокоду, на который после React смотреть без слёз нельзя. Привет php из 90-х.


                                                                                                    Надеюсь в Svelte "partials" есть.

                                                                                                      0
                                                                                                      А до тех пор я считаю что такой подход приводит к в той или иной степени разбухшему говнокоду, на который после React смотреть без слёз нельзя. Привет php из 90-х.

                                                                                                      Так вроде React — это как раз потомок php из 90х?

                                                                                                      Надеюсь в Svelte «partials» есть.

                                                                                                      Неа, нету)))) И как я писал выше, видимо не часто это нужно, раз я даже не могу придумать кейс. Вы мне тоже кейс так и не дали. Даже если он есть, но очень редкий, можно для такого редкого кейс создать один дополнительный файлик. Это не страшно.

                                                                                                      Плюс для некоторых кейсов, можно сделать что-то вроде:

                                                                                                      <template bind:this={tpl}>
                                                                                                        <h1>Hello {name}</h1>
                                                                                                      </template>
                                                                                                      
                                                                                                      {@html welcome}
                                                                                                      
                                                                                                      <script>
                                                                                                        let name = 'world', 
                                                                                                            tpl;
                                                                                                      
                                                                                                        $: welcome = name && tpl && tpl.innerHTML;
                                                                                                      </script>
                                                                                                      
                                                                                      0
                                                                                      Я наверное выскажу крамольную мысль. Но наверное все топ-фреймверки примерно равны по своим выразительным возможностям. Кроме пожалуй backbone+marionette которые можно ценить преимущественно за то что «они были первыми».

                                                                                      Если говорить о ключевых преимуществах Реакт, я на первое место ставлю как раз то, что компонент может быть классом. А это означает что на Реакте можно очень просто заниматься метапрограммированием — то есть не ручным кодированием компонентов, а генерированием компонентов, например, на основании схемы данных или же самих данных. Наверное именно поэтому в Реакт уже появилась библиотека по удобству близкая к Django при помощи которой можно очень быстро создавать админки marmelab.com/react-admin-demo Что-то внешне визуально похожее есть и на Vue, но там разработка на два порядка сложнее получается.

                                                                                      Если говорить о svelte, то я недавно обратил внимание на next-подобный фреймверк sapper см. svelte.dev/blog/sapper-towards-the-ideal-web-app-framework
                                                                                        0
                                                                                        Я наверное выскажу крамольную мысль. Но наверное все топ-фреймверки примерно равны по своим выразительным возможностям.

                                                                                        Именно так и по большей части этим всех «заразил» именно реакт. Хорошо ли это? Мое мнение не очень. Ангуляр еще пытается как-то бороться с этой модой. Все же у него есть модули и сервисы. Хотя модули вроде выпиливать будут…

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

                                                                                        Кстати, после компиляции компоненты Svelte это ES6 классы со всеми вытекающими, а исходный код компонентов, который в SFC, это и есть чистой воды метапрограммирование. Я правда так не понял причем тут генерация админки на основе данных.

                                                                                        Наверное именно поэтому в Реакт уже появилась библиотека по удобству близкая к Django при помощи которой можно очень быстро создавать админки marmelab.com/react-admin-demo Что-то внешне визуально похожее есть и на Vue, но там разработка на два порядка сложнее получается.

                                                                                        На самом деле, формулировка «в Реакт уже появилась» скорее требует «еще только». Потому что первая такая админка от тех же чуваков появилась для AngularJS в далеком 2014 году: ng-admin-book.marmelab.com

                                                                                        Если говорить о svelte, то я недавно обратил внимание на next-подобный фреймверк sapper

                                                                                        Sapper конечно чуть сыроват, но нам нем уже делают сайты и некоторые в продакшн.
                                                                                          0
                                                                                          Посмотрел на админку на Angular. Судя по коду проекта example кодить приходится все равно много. Хотя и разработчик (скорее фирма а не человек) тот же.

                                                                                          Про генерацию админок я ничего в своем посте не говорил. Просто был у меня один прототип (я даже сам не хотел этого делать т.к. не из тех кто пишет «свою cms» Задача была такая сделать cms которая была бы лучше чем все что было уже написано до меня и на это отводилось две недели плюс 4 часа на изучения Реакт) И там я как раз опирался на ту особенность что можно на основании данных конструировать компоненты на лету. Насколько я понимаю не все фреймерки позволяют сделать это. Например на riotjs я не смог это повотрить — быстро уперся в ограничения выразительных возможностей фреймверка. Хотя как правило это и не требуется в большинстве проектов.
                                                                                            0
                                                                                            Посмотрел на админку на Angular. Судя по коду проекта example кодить приходится все равно много. Хотя и разработчик (скорее фирма а не человек) тот же.

                                                                                            Тот тот. Тогда просто про реакт никто не слышал))
                                                                                            И там я как раз опирался на ту особенность что можно на основании данных конструировать компоненты на лету. Насколько я понимаю не все фреймерки позволяют сделать это. Например на riotjs я не смог это повотрить — быстро уперся в ограничения выразительных возможностей фреймверка. Хотя как правило это и не требуется в большинстве проектов.

                                                                                            Прям с нули конструировать компоненты в рантайме? Да, наверное Svelte так не умеет. Правда я и на реакт это не представляю как. Можете пример дать простой?
                                                                                              0
                                                                                              Постараюсь найти как я это делал.
                                                                                                0
                                                                                                Простого или хорошего примера нет. Могу привести фрагмент кода из приложения 3-летней давности которое было первым для меня на Реакте и не пошло дальше рабочего прототипа. Не пошло потому что я написал за две недели движок для cms и он был вполне себе рабочий. Но админка была также рабочая но я ее не успел как следует продумать. Вцелом я тогда просто для себя понял что у Реакта это достаточно интересная могла бы быть тема компонентами которые можно задавать конфигурацией и генерировать налету. Вот такой фрагмент где это происходило. Очень конечно примитивный и некрасивый.
                                                                                                ...
                                                                                                   // Компоновка из двух блоков (1 левый + 1 правый)
                                                                                                          if (Component.defaultProps && Component.defaultProps.isHalf) {
                                                                                                            if (LeftHalf !== null) {
                                                                                                              let LocalLeftHalf = LeftHalf
                                                                                                              let localLeftHalfData = leftHalfData
                                                                                                              var component = React.createElement(() => <section className='l-two-blocks' key={key++}>
                                                                                                                <LocalLeftHalf {...localLeftHalfData} key={key++}/>
                                                                                                                <Component {...block.data} key={key++}/>
                                                                                                              </section>);
                                                                                                              LeftHalf = null;
                                                                                                              return component;
                                                                                                            } else {
                                                                                                              LeftHalf = Component;
                                                                                                              leftHalfData = block.data;
                                                                                                              return;
                                                                                                            }
                                                                                                          }
                                                                                                ...
                                                                                                

                                                                                                  0
                                                                                                  Ок, а что конкретно из этого не получилось реализовать в Riot? Смотрю с точки зрения Svelte, вроде как все можно.
                                                                                                    0
                                                                                                    Я просто опишу задачу. Сайт набирался из кубиков — реально и раннее созданных компонентов с несколькими видами компоновки 1) однин компонент на ширину экрана 2) два комнонента рядом 3) один вертикальный компонент слева и два справа (один под другим) 4) аналогично один вертикальный компонент справа и два слева один под другим. Риот был тогда еще в первой версии (или тоько перешел на вторую) и, да, все это необходимо было сделать серверным рендерингом. А Риот на тот момент позволял такие манипуляции только на клиенте.

                                                                                                    Вцелом Риот сейчас уже в 4-й версии наверное все возможно. Был существенно переработан. Наконец появилась возможность гидрации. так что может быть там это и можно будет сделать.
                                                                                        +2
                                                                                        В спор касательно природы реактивности Svetle вступать не хочу, т.к. довольно долго работал с Knockout и знаю, что всё не так просто и радужно, как кажется на первый взгляд.

                                                                                        Knockout — довольно старая библиотека, полная архитектурных костылей. Пожалуйста, перестаньте судить по Knockout о всех других реактивных инструментах.

                                                                                          0

                                                                                          mayorovp, ну тут как сказать, попробовав в деле Vue2 я стал думать о KnockoutJS лучше. В KnockoutJS один ko.computed может зависеть от других ko.computed. Во Vue2 под капотом всё сводится к перекладыванию observable-leaves (что делает реализацию некоторых сложных кейсов почти невозможной). Плюс knockoutJS из коробки даёт довольно богатый инструментарий. Vue2 же даёт нам только сами компоненты. Отдельный топик работа с массивами.


                                                                                          Но судя по всему, во Vue3 будет много вкусных нововведений.

                                                                                  +1
                                                                                  Какая разница иметь несколько компонентов в одном файле или в одном каталоге? Это же просто про индивидуальность работы в команде. Если продукт не позволяет иметь более одного компонента в файле, что мешает экспортировать компоненты из этих файлов через один общий файл (тот же index)?
                                                                                    –1

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


                                                                                    Вынос их в отдельные файлы сопровождается взрывной волной бойлерплейта. Поэтому так просто никто не делает. А если так не делать, то получаем типовую vue-template-лапшу. Когда наш шаблон из простого и наглядного превращается в длинную портянку html-like кода, где понамешано всё сразу.

                                                                              0
                                                                              Нет, Вы суть не уловили… гораздо лаконичнее и я мог написать…
                                                                              Суть в том, сколько раз компонент «перерисуется» при изменении percent от 0 до 100?
                                                                              В моем случае обновление DOM («перерисовка» компонента) произойдет всего 4 раза.
                                                                                0
                                                                                Я не замерял сколько раз перерисуется компонент, но это ровно такой же код, который написали вы. У вас перерисовка блокируется операцией сравнения в shouldComponentUpdate, так?

                                                                                А Svelte просто не перерисовывает DOM, если реальное значение стейта не изменилось. Понимаете? Сразу из коробки. Он внутри знает предыдущее значение color, которое является эквивалентом вашего Math.round(this.props.percent / 30), посчитаного последний раз. Далее при изменении percent или colors, Svelte автоматически пересчитывает color (эквивалент вашего Math.round(nextProps.percent / 30)) и сравнивает предыдущее значение color с новым вычисленным. Если значение реально не поменялось, то никаких перерисовок не будет. Иными словами внутри он делает что-то вроде:

                                                                                changed.color = prevColor !== color;
                                                                                


                                                                                Это вообще все вычисления необходимые для отрисовки DOM. Одно строгое сравнение. Без rerender+reconcile, без shouldComponentUpdate. Далее сама манипуляция примерно такая:

                                                                                if (changed.color) {
                                                                                   span_1.style.color = color;
                                                                                }
                                                                                


                                                                                Где span_1 — это заранее закэшированный элемент. То есть даже querySelector по DOM не делается.
                                                                                  0

                                                                                  А для объектов, переданных параметром компонента, делается shallow equal или deep equal?

                                                                                    0
                                                                                    Конечно же shallow equal))) Зачем Svelte deep equal?
                                                                                      0

                                                                                      Ну так и React.PureComponent так же работает.

                                                                                        +1

                                                                                        "Так же" в смысле полученного результата — да. "Так же" в смысле проведенной работы — нет.


                                                                                        Svelte знает, что изменение color ведет к изменению span_1.style.color и ни к чему более. Реакт же вызовет render(), построит vDOM, сравнит его со старым, и только после этого узнает что кроме span_1.style.color менять ничего не нужно.

                                                                                          0
                                                                                          Реакт же вызовет render()

                                                                                          В том то и дело, что не вызовет — именно для этого используются shouldComponentUpdate или PureComponent.
                                                                                            0

                                                                                            Если color изменился — то ещё как вызовет.

                                                                                              –1
                                                                                              Не важно, что изменится. Если shouldComponentUpdate вернет false (а он вызывается перед render), то render не произойдет.
                                                                                                +1

                                                                                                Ау, если нам требуется изменить DOM (color-то изменился!), то какой смысл возвращать false из shouldComponentUpdate?

                                                                                                  +1
                                                                                                  color — не есть часть стейта! Меняется только percent! При его изменении не всегда нужно обновлять DOM!
                                                                                                    0

                                                                                                    Хорошо, уточняю: если percent изменился так, что теперь требуется обновить DOM — то ведь shouldComponentUpdate должен вернуть true?

                                                                                                      0
                                                                                                      Что он и делает…
                                                                                                        0

                                                                                                        И что из этого следует?

                                                                                                          0
                                                                                                          Речь тут идет о самом процессе апдейта DOM, если вы не уловили. Во-первых, просто так заюзать в вашем примере React.PureComponent все равно не получится. Описал почему тут.

                                                                                                          Но это не так важно. Вот вы написали вручную проверку значений в shouldComponentUpdate. Да теперь Реакт компонент НЕ будет обновлять DOM на абсолютно каждое изменение percent (понять бы вообще почему он в принципе когда-либо должен так делать, ведь кажется логичным не менять DOM если нет изменений).

                                                                                                          Но как только проверка сработает и shouldComponentUpdate вернет true, реакт расправит крылья и как гордый сокол полетит клевать все, что попадется ему на глаза. А именно отрендерит дубликат всего vdom этого компонента и возможно подкомпонентов (зависит от того как они реализованы) и пошагово будет сравнивать все ноды/аттрибуты/значения, чтобы в итоге просто поменять цвет текста в span.

                                                                                                          В этом примере, это не так заметно. Он всего лишь построит vdom из одной ноды с одним аттрибутом, пересчитает значения цвета (еще раз кстати), потом всего лишь соберет стили из объекта, заново применит их. Потом пошагово сравнит предыдущее дерево с новым получившимся. Сперва проверит span, потому его аттрибуты, потом выяснит какой из них изменился, потом на основе этого знания определит какую DOM операцию произвести. Просто чтобы поменять цвет.

                                                                                                          И все это против:

                                                                                                          if (changed.color) {
                                                                                                             span_1.style.color = color;
                                                                                                          }
                                                                                                          
                                                                                                            0

                                                                                                            Добрался до Svelte. Поиграл в песочнице. Интересная штука.


                                                                                                            Сгенерированный код Svelte напоминает очень хорошо оптимизированный ручной dom-mutate-код. Там случаем нет подводных камней или ограничений когда "зависимости" устроены особенно сложным образом?


                                                                                                            Насколько я понимаю тут вся магия заключается в том, что он вместо того чтобы рендерить шаблон целиком, рендерит только интерактивные его части и тут же сверяет их с прежним значением. Во многом напоминает этот самый vDom в React, но с меньшим количеством лишних телодвижений. А отличие от observable в том, что нет тяжеленных обвязок вокруг каждой переменной, нет сложностей с нетривиальным обновлением графа данных, и нет сильно усложнённого дебага.


                                                                                                            На первый взгляд такой подход кажется очень перспективным. ИМХО.

                                                                                                              0
                                                                                                              Сгенерированный код Svelte напоминает очень хорошо оптимизированный ручной dom-mutate-код.

                                                                                                              Именно так. Поэтому я называю это «писать vanillajs приложение без необходимости писать на vanillajs» )))

                                                                                                              Там случаем нет подводных камней или ограничений когда «зависимости» устроены особенно сложным образом?

                                                                                                              Можете попробовать. Если найдете такой кейс то велком в ишус и будем править.

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

                                                                                                              Я бы не сказал что напоминает vdom. В Svelte абсолюно отсутствуют как деревья, так и реконсияция оных. А все DOM манипуляции для каждого кейс заранее подготовлены. Не вижу никакой связи с работой vdom.

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

                                                                                                              Да, только статический анализ на этапе комплиции и топологический порядок.

                                                                                                              На первый взгляд такой подход кажется очень перспективным. ИМХО.

                                                                                                              Ждем вас в наших рядах: t.me/sveltejs ;-)
                                                                                                                0
                                                                                                                В Svelte абсолюно отсутствуют как деревья

                                                                                                                В #for я вижу циклы. Чем вам не деревья?


                                                                                                                так и реконсияция оных.

                                                                                                                Ну проверка changed.{anything} очень схожа с той самой реконсиляцией. Те же яйца, только сбоку. В React асимптотика решения зависит от числа DOM-звеньев, в Svelte от числа реактивных вставок. Второе, на первый взгляд, должно быть быстрее (не ручаюсь).


                                                                                                                Не вижу никакой связи с работой vdom.

                                                                                                                ^^^ А теперь? :)

                                                                                                                  0
                                                                                                                  ^^^ А теперь? :)

                                                                                                                  Не-а)))

                                                                                                                  В #for я вижу циклы. Чем вам не деревья?

                                                                                                                  Хотя бы тем, что циклы плоские.)))

                                                                                                                  Ну проверка changed.{anything} очень схожа с той самой реконсиляцией. Те же яйца, только сбоку.

                                                                                                                  Я вот такой плохой человек, поэтому люблю говорить на примерах:

                                                                                                                  <div class="foo">
                                                                                                                    <h1>Hello world</h1>
                                                                                                                    <p class="text">Lorem ipsum</p>
                                                                                                                    <form action="/login" method="post">
                                                                                                                      <input type="email" placeholder="Enter email">
                                                                                                                      <input type="password" placeholder="Enter password">
                                                                                                                      <button>Login</button>
                                                                                                                      <button type="reset">Clear</button>
                                                                                                                    </form>
                                                                                                                  </div>
                                                                                                                  

                                                                                                                  Вот такой компонент на React и Svelte (пишу на svelte, думаю сможете в уме на реакт портировать). И вот такой код:

                                                                                                                  // react
                                                                                                                  this.setState({
                                                                                                                     email: 'example@mail.com'
                                                                                                                  });
                                                                                                                  
                                                                                                                  //svelte
                                                                                                                  email = 'example@mail.com';
                                                                                                                  

                                                                                                                  Сколько операций сравнения сделает React с его vdom? Более 20ти по грубым подсчетам и это только реконсиляция.

                                                                                                                  Сколько операций должно быть выполнено? Ноль. Сколько делает Svelte? Ноль
                                                                                                                  Сколько операций в DOM должно быть сделано? Ноль

                                                                                                                  Добавим динамики:

                                                                                                                  ...
                                                                                                                  <input value={email} type="email" placeholder="Enter email">
                                                                                                                  ...
                                                                                                                  

                                                                                                                  Сколько операций сравнения сделает React с его vdom? Все также более 20-ти.
                                                                                                                  Сколько реально требуется? Одну.
                                                                                                                  Сколько сделает Svelte? Одну.
                                                                                                                  Сколко манипуляций в DOM? Одна.

                                                                                                                  Только в случае с реактом, насколько я понимаю, будет также выполнена операция получения реального DOM элемента (querySelector), а в Svelte просто:

                                                                                                                  if (changed.email) {
                                                                                                                    input0.value = ctx.email;
                                                                                                                  }
                                                                                                                  


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

                                                                                                                  Разница более чем существенная, а ваше обобщение «мол все одно» слишком уж масштабное.
                                                                                                                    0
                                                                                                                    Хотя бы тем, что циклы плоские.)))

                                                                                                                    Не очень понял вас. #for в #for не создаст вложенного цикла?


                                                                                                                    Сколько сделает Svelte? Одну.

                                                                                                                    Svelte сделает столько сравнений сколько у вас {}. В этом и параллель. Я выше об этом и писал. Асимптотика зависит от разных вещей. Вариант со Svelte быстрее. Можете условно считать что у Svelte вместо vdom vexpressions. Аналог реконсиляции находится там где проходят проверки на changed.{anything}

                                                                                                                      0
                                                                                                                      Не очень понял вас. #for в #for не создаст вложенного цикла?

                                                                                                                      Может я не понял, но в Svelte нет #for. Есть #each но какое отношение это имеет в деревьям vdom все равно не ясно.

                                                                                                                      Svelte сделает столько сравнений сколько у вас {}. В этом и параллель. Я выше об этом и писал.

                                                                                                                      Просто это не так)) Видимо пример придется все же продолжить, чтобы вы разобрались.

                                                                                                                      Добавим еще чуть динамики:

                                                                                                                      ...
                                                                                                                      <h1>Hello {email}</h1>
                                                                                                                      ...
                                                                                                                      

                                                                                                                      Сколько операций сравнения Реакт? Все еще более 20-ти.
                                                                                                                      Сколько операций сравнения надо? Одну.
                                                                                                                      Сколько сделает Svelte? Одну.
                                                                                                                      Сколько операций в DOM? Две.

                                                                                                                      Можете условно считать что у Svelte вместо vdom vexpressions. Аналог реконсиляции находится там где проходят проверки на changed.{anything}

                                                                                                                      Вы серьезно думаете что вот это аналог реконсиляции vdom?:

                                                                                                                      if (changed.email) {
                                                                                                                        set_data(t1, ctx.email); // внутри хелпера: t1.data = ctx.email
                                                                                                                        input0.name = ctx.email;
                                                                                                                      }
                                                                                                                      

                                                                                                                      Ну тогда получается что все фреймворки работают по сути как AngularJS. У всех есть своеобразная форма change detection. Все одно и тоже. Зачем тогда нам с AngularJS вообще было слезать? Писали бы на нем и радовались жизни )))))
                                                                                                                        0
                                                                                                                        Вы серьезно думаете что вот это аналог реконсиляции vdom?

                                                                                                                        Ну да. А что вас в этом смущает?


                                                                                                                        Все одно и тоже

                                                                                                                        Наличие аналогий не говорит о том, что это одно и тоже. На деле подходы очень разные и их разнообразие меня радует. С чего вы вообще взяли, что я считаю это всё одинаковым?


                                                                                                                        Я столкнулся уже как минимум с 4 разными способами обеспечить "реактивность". У Svelte довольно оригинальный подход.

                                                                                                                          0
                                                                                                                          Ну да. А что вас в этом смущает?

                                                                                                                          Эм, ну тогда ладно)

                                                                                                                          С чего вы вообще взяли, что я считаю это всё одинаковым?

                                                                                                                          Хм, ну даже не знаю… Может быть поэтому?:

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

                                                                                                                          Svelte ничего не рендерит перед проверкой, только после. Реакт сперва рендерит vdom, потом проверяет, потом рендерит dom.

                                                                                                                          Во многом напоминает этот самый vDom в React, но с меньшим количеством лишних телодвижений.

                                                                                                                          Тогда можно было написать, «Svelte во многом напоминает вообще все что только можно, потому что у всех есть аналог cd». Да и вообще, человечество еще не придумало способа сравнить что-то, кроме как сравнить, то есть все очень похоже и напоминает друг друга))))

                                                                                                                          Я столкнулся уже как минимум с 4 разными способами обеспечить «реактивность». У Svelte довольно оригинальный подход.

                                                                                                                          Вот тут вы правы, просто без компиляции и мета-программирования это не получилось бы. Поэтому столько упора делается на то, что svelte — это компилятор.
                                                                                                                            0
                                                                                                                            Svelte ничего не рендерит перед проверкой, только после. Реакт сперва рендерит vdom, потом проверяет, потом рендерит dom

                                                                                                                            Да, да, всё так. Мне стоило вычитать тот комментарий перед отправкой. Sorry что запутал.


                                                                                                                            Тогда можно было написать, «Svelte во многом напоминает вообще все что только можно

                                                                                                                            Отнюдь. Судите сами: он совсем не напоминает KnockoutJS или Vue. Там ведь нет никаких сравнений. Мы просто обновляем значение, и, после этого, уведомляем всех подписчиков. Какой ценой — отдельная песня, но суть вещей другая.


                                                                                                                            А здесь мы последовательно пробегаем по всем возможным включениям, сверяясь изменилось ли наше поле или нет.


                                                                                                                            что svelte — это компилятор

                                                                                                                            Вспомнился Imba. Тоже компилятор.

                                                                                                                              0
                                                                                                                              Отнюдь. Судите сами: он совсем не напоминает KnockoutJS или Vue. Там ведь нет никаких сравнений. Мы просто обновляем значение, и, после этого, уведомляем всех подписчиков. Какой ценой — отдельная песня, но суть вещей другая.

                                                                                                                              Опять же не уверен как это в KnockoutJS, но в Vue все тот же vdom, что и в реакт. Разница лишь в том, что Vue кладет изменение в очередь и обновляет их в конце текущего тика, то есть изменени просходят асинхронно, а не синхронно как в React. Сам принцип Vdom при этом никак не меняется.

                                                                                                                              А здесь мы последовательно пробегаем по всем возможным включениям, сверяясь изменилось ли наше поле или нет.

                                                                                                                              Последовательно «по всем значениеям» это очень далеко от «последовательно по всему дереву».

                                                                                                                              Вспомнился Imba. Тоже компилятор.

                                                                                                                              Да есть такой: twitter.com/Rich_Harris/status/1065992585095929857
                                                                                                                                0

                                                                                                                                Кстати да, Vue использует vDom. Совершенно вылетело из головы. Несмотря на то, что у них observer под капотом. Не знаю, что их побудило к этому, но наверное на то были причины. В knockout же мы имеем множество функций вида val => domNode.setAttribute('title', val), которые вызываются при изменении значения observable. А у Vue, да, гибридный подход. Совсем забыл про это. Надо будет нарыть — зачем оно там.


                                                                                                                                Последовательно «по всем значениеям» это очень далеко от «последовательно по всему дереву».

                                                                                                                                С этим сложно спорить. Поэтому в ваших бенчмарках Svelte и показывают большую производительность.


                                                                                                                                Да есть такой: twitter.com/Rich_Harris/status/1065992585095929857

                                                                                                                                У него тут неплохой результат кстати. Надеюсь это не тот самый бенчмарк который они учудили ранее (там совершенно отвратно написанные React и Vue решения, которые ну просто никак не могут не тормозить).

                                                                                                                          0
                                                                                                                          Может я не понял, но в Svelte нет #for. Есть #each но какое отношение это имеет в деревьям vdom все равно не ясно.

                                                                                                                          Не к vDom, а к деревьям. Впрочем не суть. Мы опять углубляемся в скучные дебри терминологии.

                                                                                                0

                                                                                                Нет. PureComponent отсекает рендеринг в моменте изменения параметров компонента.

                                                                                                  +2

                                                                                                  Ну так percent-то по условию изменился...

                                                                                                0
                                                                                                Я бы не сказал, что точно также, но да, там хак с shouldComponentUpdate для таких простых случаев уже не актуален, но насколько я помню там есть конкретные ограничения на его использование и нельзя просто взять и сделать все реакт компоненты React.PureComponent. В Svelte это просто так работает, потому что он в принципе не пытается все рендерить.

                                                                                                Ну и опять же, как в примеру выше применить React.PureComponent? Он же сам имплементирует shouldComponentUpdate, но только для стейта и пропсов. То есть придется вводить такой же color, как я ввел в примере на Svelte и тогда везде императивно связывать percent (пропс) и color (внутренний), то есть при каждом изменении percent заново вычислять color. Как по-другому то? В реакт же нет реактивности. Получается мы избавимся от ручной проверки в shouldComponentUpdate, но получим какой-нить componentWillReceiveProps. Короче все равно не то.
                                                                        0
                                                                        В Svelte пропагандируется one-file-component. То есть стили, код и шаблон все в оном файле. При таком подходе сразу отрубается множество полезных инструментов статического анализа кода, форматирования и тд.
                                                                          +1
                                                                          Чем же лучше react/angular/flutter & co, где шаблон хорошо разбавлен кодом (или наоборот)? Уж лучше один файл но в нём отдельно шаблон и код, чём php-style 15-ти летней давности, пусть и с улучшенным синтаксисом.
                                                                            0

                                                                            В angular код отделён от шаблона, и они в принципе в разных файлах лежат.

                                                                              0
                                                                              Прошу прощения. Видимо, мне просто попался такой фрагмент кода на angular — со вставками markup, и я экстраполировал на весь фреймворк.
                                                                                0
                                                                                В angular действительно шаблоны можно инлайнить в код компонента как строку, но это опциональная возможность. Как правило шаблоны там в отдельных файла что хорошо. А вот Svelte насколько я понимаю не позволяет использвать 3-files-component модель разработки которая по моему мнению предпочтительна.
                                                                                  0
                                                                                  А вот Svelte насколько я понимаю не позволяет использвать 3-files-component модель разработки которая по моему мнению предпочтительна.

                                                                                  Позволяет, можно делать так, после установки специального препроцессора:

                                                                                  <template src="template.html"></template>
                                                                                  <script src="script.js"></script>
                                                                                  <style src="style.css"></style>
                                                                                  

                                                                                  Только обычно это не нужно и не удобно. Если компонент радумается, что хочется разделить его, то скорее всего был нарушен принцип single responsibility и компонент следует отрефакторить.
                                                                                    +1
                                                                                    Если компонент радумается, что хочется разделить его, то скорее всего был нарушен принцип single responsibility и компонент следует отрефакторить.
                                                                                    Разделение ведь нужно не потому что файл раздувается, а чтобы самый различный туллинг мог работать с файлами. Но если на то пошло, то как раз все мешать в один файл и есть нарушение принципа single responsibility. Что в Vue что в Svelte какая-то нездоровая мода.
                                                                                      0
                                                                                      Разделение ведь нужно не потому что файл раздувается, а чтобы самый различный туллинг мог работать с файлами.

                                                                                      Тулинг можно доработать. Все фреймворки требуют кастомного туллинга в любом случае: в React изначально не было туллинга для jsx, во Vue для SFC, в Angular тоже полно кастомных вещей, те же декораторы и TS. Все это в какой-то момент времени требовало доработки туллинга. Отказывать в удобстве разработки из-за временного несовершенства туллинга довольно глупо.

                                                                                      Но если на то пошло, то как раз все мешать в один файл и есть нарушение принципа single responsibility. Что в Vue что в Svelte какая-то нездоровая мода.

                                                                                      Странно вы делите приложение по responsibility. Для меня single responsibility — это про фукнционал, а не про деление на языки. В этом смысле единый, инкапсулированный компонент, решающий одну функциональную задачу — это вполне себе single responsibility.

                                                                                      Если вы придерживаетесь другого мнения — я написал выше как можно разделить на отдельные файлы.
                                                                                        –1
                                                                                        > React изначально не было туллинга для jsx, во Vue для SFC

                                                                                        Как раз по той же причине по которой и у свелти, все эти поделки пропагандируют SFC, а React еще доверху намешал кода с шаблонами в своем JSX (фирменнный PHP спагетти-стиль 15 летней давности).

                                                                                        > Все фреймворки требуют кастомного туллинга в любом случае

                                                                                        Это не так. Если все в отделных файлах, то доработки никакие не нужны, тулы просто сканирут файл и все.
                                                                                          0
                                                                                          Я бы не сказал что React пропагандируют SFC. У них была попытка реализации, но неудачная. Реальные SFC только у Vue и Svelte.

                                                                                          Это не так. Если все в отделных файлах, то доработки никакие не нужны, тулы просто сканирут файл и все.

                                                                                          Я писал про фреймворки. Давайте уже без «воды». Назовите фреймвок, который не требует костомного туллинга?
                                                                                            –1
                                                                                            Я писал про фреймворки. Давайте уже без «воды». Назовите фреймвок, который не требует костомного туллинга?
                                                                                            Когда у тебя код во внешних файлах типового формата, то типовые тулы будут работать вне зависимости от фреймворка потому что это ведь просто JS/TS/CSS/SCSS/HTML/итд файлы которые не нужно кастомным образом выколупывать из SFC для анализа или какой-либо post обработки.

                                                                                            Просто нужно понимать что исходный код не требует некой логической группировки (SFC) и даже наоборот лучше делить код на мелкие части (даже например просто банально потому что будет меньше вероятность конфликтов при мерже). Но группировка может быть нужна потребителю кода или при дистрибуции кода и вот там уже имеет смыслы делать некую логическую группировку и компоненты.
                                                                                              0
                                                                                              Когда у тебя код во внешних файлах типового формата, то типовые тулы будут работать вне зависимости от фреймворка потому что это ведь просто JS/TS/CSS/SCSS/HTML/итд


                                                                                              Что есть типовой формат и почему TS/SCSS вдруг стали типовыми? Для них сразу тулзы были написаны? А раз нет, тогда почему вы считаете что SFC не станет точно также типовым. Да и сейчас уже SFC в Svelte это тоже вполне себе типовой формат, HTML называется. За исключением языка шаблонов HTMLx, все остальное вполне себе поддается стандартному для HTML файлов туллингу.

                                                                                              файлы которые не нужно кастомным образом выколупывать из SFC для анализа или какой-либо post обработки.

                                                                                              Ничего «выколупывать» самому и не надо. Есть препроцессоры, которые как раз делают это за нас.

                                                                                              Просто нужно понимать что исходный код не требует некой логической группировки (SFC) и даже наоборот лучше делить код на мелкие части (даже например просто банально потому что будет меньше вероятность конфликтов при мерже). Но группировка может быть нужна потребителю кода или при дистрибуции кода и вот там уже имеет смыслы делать некую логическую группировку и компоненты.

                                                                                              Не согласен тут. Значительно удобнее работать с компонентом как с единой единицей. Нужно вынести отдельно? Писал выше как.
                                                                                                +1
                                                                                                Да и сейчас уже SFC в Svelte это тоже вполне себе типовой формат, HTML называется. За исключением языка шаблонов HTMLx, все остальное вполне себе поддается стандартному для HTML файлов туллингу.

                                                                                                Лично меня очень интересует именно TS-тулинг. То есть такая штука, которая подскажет мне, у какой переменной какие свойства имеются.


                                                                                                И вот его-то в Svelte и нету...


                                                                                                А HTML-тулинг как раз особо и не нужен, разве что закрывающие тэги автоматом проставлять.

                                                                                                  0
                                                                                                  Лично меня очень интересует именно TS-тулинг. То есть такая штука, которая подскажет мне, у какой переменной какие свойства имеются.

                                                                                                  И вот его-то в Svelte и нету…

                                                                                                  Есть такое, да, но речь как раз о том, что все это вещи которые нарабатываются со временем силами сообщества. Сейчас минимально это выглядит так:



                                                                                                  Да, не густо, но ребята из русскоязычного сообщества пилят поддержку например вот такой штуки:

                                                                                                  marketplace.visualstudio.com/items?itemName=ardenivanov.svelte-intellisense

                                                                                                  Это уже поинтереснее.
                                                                              0
                                                                              php-style 15-ти летней давности
                                                                              JSX пропагандируемый реактом и есть 15-ти летней давности спагетти-код-стайл, видимо потому что в FB изначально было много PHP кодеров и дос сих пор таковые диктуют правила игры имея огромные рычаги маркетингового влияния.
                                                                            +1
                                                                            Агрессивный маркетинг, но по сути это как картинка про «еще один стандарт»,
                                                                            только вот нового ничего Svelte ни привносит, более того несколько искажает то что есть в попытке выдать за новое
                                                                              0
                                                                              То есть полная компиляция высокоуровневого декларативного кода в низкоуровневый императивный код — это ничего нового в контексте JS фреймворков? Выкидывание из рантайма большей части тяжелых операций, таких как render/reconcile в vdom, тоже? Можете рассказать, где еще используется тот же принцип?
                                                                                –4
                                                                                Извините, уважаемый, но у меня как-то даже близко язык не поворачивается JS в любой форме называть низкоуровневым.
                                                                                  0
                                                                                  То есть вы ушли от ответа, почему вы утвердаете, что Svelte не привносит ничего нового?

                                                                                  Код на любом языке может быть как более высокоуровневым, так и более низкоуровневым для этого языка. Речь не про сам язык, а про то как писать код на нем. Прямые манипуляции в DOM очевидно более низкоуровневое использование JS, чем декларативное изменение состояние с последующей синхронизацией с DOM.
                                                                                    –2
                                                                                    Ок, я согласен, действительно, я достаточно стар поэтому сравниваю «низко/высокоуровневость» целиком языками (помните С/С++/Asm?) а не в рамках одного языка, что как вечно замечено также вполне приемлемо.
                                                                                    Относительно компиляции, в той или иной мере это все современные фреймфорки делают (SFC в Vue, и даже если взять тот же jsx в реакте — здесь тоже нужна компиляция)
                                                                                    По моему личному мнению Svelte выглядит ближе к jquery чем к к современным фреймворкам, а это шаг назад а не вперед (и фанатики с пеной у рта доказывающие его превосходство над все сущим только добавляют негатива).
                                                                                    Но скажу честно, мне будет интересно во что он вырастит через год или два.
                                                                                      +2
                                                                                      Ок, я согласен, действительно, я достаточно стар поэтому сравниваю «низко/высокоуровневость» целиком языками (помните С/С++/Asm?) а не в рамках одного языка, что как вечно замечено также вполне приемлемо.

                                                                                      Верю вам на слово, что вы старее меня))) Однако, я в свое время тоже 4 года писал на С/С++ и все же стараюсь отделять мух от котлет.

                                                                                      Относительно компиляции, в той или иной мере это все современные фреймфорки делают (SFC в Vue, и даже если взять тот же jsx в реакте — здесь тоже нужна компиляция)

                                                                                      Боюсь что вы путаете компиляцию и транспиляцию. Никакой JSX и даже SFC во Vue и близко не делают то, что делает Svelte. Первый по сути превращает декларативные определения <Component /> в императивные вызовы React.createElement(). Второй всего лишь другой вид записи new Vue(options).

                                                                                      По моему личному мнению Svelte выглядит ближе к jquery чем к к современным фреймворкам, а это шаг назад а не вперед (и фанатики с пеной у рта доказывающие его превосходство над все сущим только добавляют негатива).

                                                                                      Интересное умозаключение. Поделитесь на чем оно основано? Jquery — это низкоуровневая библиотека-обертка над императивными манипуляциями в DOM, которая склоняла нас писать в event-based стиле. Svelte — это высокоуровневый компилятор SFC в ванильные компоненты без зависимостей, который склоняет к использованию реактивного декларативного state-based программирования. Я бы хотел узнать цепочку рассуждений, которая склонила вас полагать, что Svelte ближе к Jquery, нежели к React/Vue/Angular.
                                                                              0
                                                                              У Svelte, равно как и множества других реактивных фреймворков, есть большой недостаток — это динамическое (пере)создание элементов при обновлении их содержимого. К примеру, даже сравнительно статический фрагмент из банального &lth1>Hello {name}&lt/h1> превращается в такой код:
                                                                              c() {
                                                                              	h1 = element("h1");
                                                                              	t0 = text("Hello ");
                                                                              	t1 = text(name);
                                                                              	t2 = text("!");
                                                                              },
                                                                              
                                                                              m(target, anchor) {
                                                                              	insert(target, h1, anchor);
                                                                              	append(h1, t0);
                                                                              	append(h1, t1);
                                                                              	append(h1, t2);
                                                                              },

                                                                              Вопрос — зачем? Если элемент статический и долгоживущий — почему на этапе компиляции не создать его один раз и потом не менять только содержимое, храня только ссылку на единожды созданный элемент?

                                                                              Если постоянно динамически это делать, это серьезный удар по производительности (если, конечно, это не контент который меняется раз в сто лет), не говоря уже о размере кода который нужен для создания всех элементов (если их много).

                                                                              Собственно сам browser намного быстрее всё отрендерит и построит из html, чем из js-кода, изменения только контента намного быстрее чем полное пересоздание элементов.

                                                                              Пока же, увы, тенденция такова что темплейты в html просто тупо транслируются в js, фактически убивая всё то хорошее ради чего был создан собственно html (попробуйте ради интереса сделать в свелте &ltdiv>static text&ltdiv> — получите тоже кусок js).

                                                                              Да, оно работает, в большинстве случаев достаточно быстро чтобы пользователи не видели разницы, но это всё равно неэффективно — как по использованию процессора, так и памяти.
                                                                                +3
                                                                                Вопрос — зачем? Если элемент статический и долгоживущий — почему на этапе компиляции не создать его один раз и потом не менять только содержимое, храня только ссылку на единожды созданный элемент?

                                                                                m — это операция mount, она выполняется только 1 раз. Смотрите функцию update, там всё именно так как вы хотели!

                                                                                  –3
                                                                                  Если переменная name изменяется, элемент будет пересоздаваться — весь, снова и снова — в этом я и вижу проблему.
                                                                                    +1

                                                                                    Нет, не будет:


                                                                                            p(changed, ctx) {
                                                                                                if (changed.name) {
                                                                                                    set_data(t1, ctx.name);
                                                                                                }
                                                                                            },

                                                                                    Если вы сомневаетесь по поводу set_data — вот её реализация:


                                                                                    export function set_data(text, data) {
                                                                                        data = '' + data;
                                                                                        if (text.data !== data) text.data = data;
                                                                                    }
                                                                                      +1

                                                                                      Нет, и в Свелте, и в Реакте, и в Ангуляре будет обновляться только та часть DOM-дерева, которая реально изменилась. Если изменилась text node, то тоже только она изменится, а сам элемент останется нетронутым. Просто механизм, которым обеспечивается минимально необходимое изменение дерева, разный.

                                                                                        –1
                                                                                        Ok, хорошо — но остается всё же массивный объем кода для создания даже статики. Банальный
                                                                                        <div>static text</div>
                                                                                        создается посредством js:
                                                                                        div = element("div");
                                                                                        div.textContent = "static text";
                                                                                        
                                                                                        т.е. для сравнительного большого темплейта будет куча кода. А куча кода это куча кода — даже если он выполняется один раз.

                                                                                        Зачем такой огород если можно просто скормить браузеру собственно html с нужными вставками?
                                                                                          0

                                                                                          Банальный <div>static text</div> на самом деле не так уж прост. Браузер создаст все те же DOM-элементы внутри, что и мы сами руками, но при этом у нас не будет возможности переиспользовать div и обновить только textContent.


                                                                                          Еще есть вот такой доклад, например, в котором рассказывается об этом больше: https://habr.com/en/company/oleg-bunin/blog/310868/