Пишите меньше кода

Хайп по Svelte после недавнего релиза 3 версии фреймворка всё-таки имеет место быть, чему свидетельствуют сильно возросшее комьюнити и огромное количество вопросов как в официальном чате, так и в нашем рускоязычном telegram-канале. Всё больше разработчиков украдкой или всерьёз присматриваются к этой технологии и задумываются о её применении в своих новых проектах. Для этих разработчиков и всех прочих интересующихся темой максимально эффективного написания кода, Rich Harris, автор и идеолог фреймворка, опубликовал статью о том, как Svelte помогает разработчику минимизировать усилия при создании современных реактивных web-приложений, перевод которой я и предлагаю ниже.


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


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


На самом деле, широко известно, что, с увеличением кодовой базы приложения, время разработки проекта и количество багов растут даже не с линейной, а с квадратичной зависимостью. Этим можно объяснить наше подсознательное поведение, когда пулл-реквесту на 10 строк мы с лёгкостью уделим такой уровень внимания, который редко достаётся коду размером более 100 строк. А как только код становится слишком длинным, и перестаёт помещаться на одном экране, когнитивные усилия, необходимые для его понимания, значительно возрастают. Мы пытаемся исправить ситуацию путём рефакторинга и добавлением комментариев — действия, которые почти наверняка приводят к ещё бо́льшему количеству кода. Это порочный круг.


Мы все немного одержимы, верно? Мы следим за производительностью приложения, размером бандла и всего прочего, что мы можем хоть как-то измерить, но мы редко обращаем внимание на объём кода, который пишем.


Читаемость кода — это важно


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


for (let i = 0; i <= 100; i += 1) {
    if (i % 2 === 0) {
        console.log(`${i} — чётное`);
    }
}

… во что-то неудобоваримое:


for (let i = 0; i <= 100; i += 1) if (i % 2 === 0) console.log(`${i} — чётное`);

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


Да, я говорю о Svelte


Сокращение объёма кода, который нужно писать, является очевидным преимуществом Svelte. Чтобы проиллюстрировать это, давайте посмотрим на очень простой компонент, реализованный на React, Vue и Svelte. Сначала версия Svelte:


<script>
    let a = 1;
    let b = 2;
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {a + b}</p>

Посмотреть в действии


Как мы сделаем то же самое в React? Скорее всего, это будет выглядеть примерно так:


import React, { useState } from 'react';

export default () => {
    const [a, setA] = useState(1);
    const [b, setB] = useState(2);

    function handleChangeA(event) {
        setA(+event.target.value);
    }

    function handleChangeB(event) {
        setB(+event.target.value);
    }

    return (
        <div>
            <input type="number" value={a} onChange={handleChangeA}/>
            <input type="number" value={b} onChange={handleChangeB}/>

            <p>{a} + {b} = {a + b}</p>
        </div>
    );
};

И, наконец, в Vue:


<template>
    <div>
        <input type="number" v-model.number="a">
        <input type="number" v-model.number="b">

        <p>{{a}} + {{b}} = {{a + b}}</p>
    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                a: 1,
                b: 2
            };
        }
    };
</script>

Иначе говоря, требуется 442 символа в React и 263 символа в Vue, чтобы достичь чего-то, что в Svelte занимает 145 символов. Версия React буквально в три раза больше!


Подсчёт символов я выполнил путем копирования кода в буфер обмена и запуском команды pbpaste | wc -c в терминале


Такая сильная разница скорее исключение — из моего опыта, компонент React обычно примерно на 40% больше, чем его эквивалент на Svelte. Давайте теперь взглянем на особенности Svelte, которые позволяют компактнее излагать наши идеи.


Элементы верхнего уровня


В Svelte компонент может иметь столько элементов верхнего уровня, сколько вам нужно. В React и Vue компонент обязан иметь единственный элемент верхнего уровня — в случае React попытка вернуть два элемента верхнего уровня из функции компонента приведет к синтаксической ошибке. Вы можете использовать фрагмент — <> — вместо <div>, но дополнительный уровень вложенности никуда не денется.


В Vue разметка должна быть размещена внутри элемента <template>, который, на мой взгляд, тут лишний.


Привязки


В React мы должны самостоятельно обрабатывать события полей ввода вроде <input>:


function handleChangeA(event) {
    setA(+event.target.value);
}

Это не просто весьма скучная конструкция, занимающая место на экране, это ещё и дополнительная часть кода, где могут появиться ошибки. Концептуально, значение текстового поля привязано к значению a и наоборот, но это отношение не выражено чётко — вместо этого у нас есть два тесно связанных, но физически отдельных фрагмента кода (обработчик события и свойство value={a}). Кроме этого, мы должны помнить, что необходимо принудительно привести строковое значение в числовое с помощью оператора +, иначе 2 + 2 будет равно 22 вместо 4.


Как и в Svelte, у Vue есть свой способ выразить привязку — атрибут v-model, но и тут мы должны быть внимательны и использовать v-model.number, несмотря на то, что берём значение из <input type="number">.


Стейт


В Svelte обновление локального состояния компонента происходит с помощью простого оператора присваивания:


let count = 0;

function increment() {
    count += 1;
}

В React мы используем хук useState:


const [count, setCount] = useState(0);

function increment() {
    setCount(count + 1);
}

Тут сильно больше постороннего шума — оба фрагмента кода выражают одну и ту же концепцию, но во втором случае было использовано на 60% больше символов. Поэтому, когда вы читаете такой код, вам придётся приложить гораздо больше усилий, чтобы понять замысел автора.


Ну а в Vue у нас есть экспорт по умолчанию, содержащий функцию data, которая возвращает литерал объекта со свойствами, соответствующими локальному состоянию приложения. Отмечу также, что в Vue нельзя просто импортировать и сразу использовать в разметке такие вещи, как функции из внешних файлов и дочерние компоненты, так как сначала их необходимо 'зарегистрировать', указав в определённой части экспорта по умолчанию.


Забудем про шаблонный код


Это лишь малая часть возможностей Svelte, которые помогают с минимальными усилиями создавать UI приложения. Есть ещё много других — например, реактивные объявления, которые по своей сути выполняют работу функций useMemo,useCallback и useEffect из React без лишнего многословного шаблонного кода (который при этом сильно нагружает сборщик мусора созданием инлайновых функций и массивов при каждом изменении состояния приложения).


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


Полезные ссылки


Документация на русском по Svelte 3
Учебник на русском по Svelte 3
Примеры на русском по Svelte 3
Русскоязычный канал Telegram

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

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

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

    +6

    Больше похоже на самооблизывание, чем на статью. Я так и не узнал, зачем мне стоит писать меньше кода. Серьезно, тяжело разобрать свой код с хорошими комментариями? Чувак, ну, ты делаешь что-то не так. Н

      +10
      Серьезно, тяжело разобрать свой код с хорошими комментариями?


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

      А вот если к этому проекту (или к этой части в большом проекте) ты возвращаешься спустя 4 месяца — то даже свой собственный код воспринимается так же тяжело как и чужой.
        –4

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

          +3
          Если смотреть пример, то помимо уменьшения кода, улучшелось его понимание/восприятие, это реальный плюс.
            +1
            > это не настолько большая проблема
            Подавляющее большинство времени программист меняет существующий код, а не пишет новый. С чего это упрощение этого процесса не является важной проблемой?
              0
              Говорят, что пишут обычные программисты в день обычно мало: habr.com/ru/post/102620

              А вот думают, читают и решают как раз очень много.
          +7
          В статье на мой взгляд хорошо объяснено.
          Во-первых, непосредственно при написании больше шансов допустить ошибку, во-вторых, при рефакторинге, большое количество кода редактировать куда тяжелее. Даже психологически: мысль «вот такенную телегу мне придётся сейчас разбирать» вполне может выбить из потока. Документирование каждой детали такого кода тоже не спасает, каждый раз при рефакторинге придётся поддерживать ещё и документацию, и в один момент произойдёт рассинхрон документации и реального кода.

          Чем меньше кода и чем лаконичнее документация — тем лучше. Другое дело, что в реальной жизни всё равно придётся идти на компромиссы между количеством кода и например удобством тестирования и управлением зависимостями.
            +1
            В статье это очень плохо объяснено. Уж извините, но по мне, объяснение в духе «используйте Basic, а не Java, потому что „Hello world“ на Basic пишется в одну строчку, а в Java — в 10» отдаёт глупостью…
            А всё потому, что на языке программирования и фреймворке мы пишем не «Hello world»-ы, а многокомпонентные приложения из тысяч строк кода, и взаимодействие кода с браузером клиента, удобство описания и взаимодействия компонентов, упаковка кода для клиента, отладка (на девелоперской, серверной и клиентской стороне!)… все эти вещи очень сильно влияют на разработку. А здесь даже до уровня «как написать if» не добрались, что уж говорить даже про модульные компоненты. Дело не в компромиссах из реальной жизни… А лишь в компромисах между «hello world» и реальным кодом.
            Авторы, как вы собираетесь эти var a=… упаковывать и импортить вообще? Компоненты в React и Vue — именно этот вопрос решают. Их может быть несколько на один файл, им можно настроить области видимости. Первый попавшийся пример из интернета: github.com/HugoDF/vue-multiple-components-in-sfc/blob/master/02-global-component-string-template/src/App.vue, там объявлено два компонента: HelloWorld/'hello-world' и default/'app' (имя переменной компонента — по имени файла шаблона). Я в любой момент могу переименовать default в любое другое имя. У меня есть возможность инициализации этих переменных из различных источников и в разные моменты жизненного цикла компонента. А у вас псевдо-глобальные переменные почему-то этому решению соответствуют…
              +1

              Дело в том, что Svelte — он не React и не Vue. Упаковывает и импортит компилятор. Вам об этом думать не надо. В этом и смысл — чтобы не писать кучу шаблонного кода(т.е. boilerplate), который обязательно должен быть в фреймворке с runtime. В учебнике чуть подробнее про импорты и вложенные компоненты(полистайте вперед немного, там последовательное объяснение и выполнение уроков)

                –2
                кучу шаблонного кода(т.е. boilerplate), который обязательно должен быть в фреймворке с runtime

                С чего бы?

                  0
                  С чего бы?

                  Потому что обычно фреймворк заранее не может знать какую его часть вы использовать НЕ будете. Svelte же предлагает иной подход.

                    +1

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


                    Я хотел сказать, что runtime предполагает обязательные ритуальные действия, например как у помянул Rich в этой статье для Vue:


                    ...
                    import Component from 'component';
                    
                    export default {
                      ...
                      components: {
                        Component
                      }
                    ...
                    }

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

                      0
                      Т.е. нельзя просто импортировать компонент и сразу вставить его в разметку.

                      Можно даже не импортировать, не устанавливать, а сразу использовать. Имея при этом рантайм. Пример я тут уже приводил.

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

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

                        –1
                        Потому что обычно фреймворк заранее не может знать какую его часть вы использовать НЕ будете.

                        А тришейкинг куда делся?

                          0
                          обязательно

                          ...


                          обычно

                          Вы уж определитесь там.)

                      –1
                      А всё потому, что на языке программирования и фреймворке мы пишем не «Hello world»-ы, а многокомпонентные приложения из тысяч строк кода, и взаимодействие кода с браузером клиента, удобство описания и взаимодействия компонентов, упаковка кода для клиента, отладка (на девелоперской, серверной и клиентской стороне!)… все эти вещи очень сильно влияют на разработку. А здесь даже до уровня «как написать if» не добрались, что уж говорить даже про модульные компоненты. Дело не в компромиссах из реальной жизни… А лишь в компромисах между «hello world» и реальным кодом.

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

                      Авторы, как вы собираетесь эти var a=… упаковывать и импортить вообще? Компоненты в React и Vue — именно этот вопрос решают.

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

                      Пишем компонент:
                      <script>
                      let privateVar = 1, 
                          publicProp = 2;
                      
                      function privateFunc() { ... }
                      function publicMethod() { ... }
                      
                      export { // публичный интерфейс
                        publicProp,
                        publicMethod
                      };
                      </script>
                      


                      Используем через инстанс компонента или декларативно:

                      <Nested bind:this={comp} publicProp={3} />
                      
                      <script>
                        import Nested from './Nested.svelte';
                      
                        let comp; // или через инстанс
                        ...
                        comp.publicProp = 4;
                        comp.publicMethod();
                      </script>
                      


                      Их может быть несколько на один файл,

                      Это скорее минус чем плюс и нужно бить по рукам. Один компонент — один файл. Без исключений. Если нужно, например, представить несколько логически связанных компонентов как единый «пакет», то проще и нагляднее сделать так:

                      // multipleComponents/index.js
                      import HelloWorld from './HelloWorld.svelte';
                      import Default from './Default.svelte';
                      export default Default;
                      export HelloWorld;
                      


                      Я в любой момент могу переименовать default в любое другое имя.

                      Если вы про устаревший механизм «регистрации» компонентов, то например в реакт его никогда не было. Да и нативные импорты позволяют вам переименовывать компоненты и так:

                      <Posts />
                      <Message />
                      
                      <script>
                        import Posts from './Listview.svelte';
                        import { HelloWorld as Message } from './multipleComponents/';
                      </script>
                      


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

                      В Svelte все тоже самое, только лаконичнее. Более того, синтаксис Svelte 2 был очень похож на Vue. Если уж быть совсем точным, потому что синтаксис Vue был изначально скопирован с Ractive, автором которого является автор Svelte. Так что можно сказать, тот синтаксис, который вы так полюбили, придумал автор статьи ;-)

                        +1
                        Это скорее минус чем плюс и нужно бить по рукам. Один компонент — один файл.

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


                        Если нужно, например, представить несколько логически связанных компонентов как единый «пакет», то проще и нагляднее сделать так:

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


                        Кстати, а как в svelte с ленивой подгрузкой компонентов дела обстоят?

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

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

                          А тут на лицо полезный бойлерплейт. Во-первых, он делает структуру приложения понятно и прозрачной. Во-вторых, «много-много мелких компонентов» это условное понятие, потому что пока компонент мелкий, а знавтра новая задача и он уже большой. Один разработчик привык искать его в файле с другим компонентов, а другой был вынужден вынести его в отдельный файл. В-третьих, сейчас в этом месте нужен один подкомпонент, а завтра надо свитчить между 5-ю, тоже в этот же файл засунем все? В-четвртых, сегодня этот компонент нужен в одном месте, а завтра в 2-х. Получается постоянный refactoring-driven-development даже там, где он не нужен изначально.

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

                          /src/
                            /components/
                              /Grid/
                                index.js
                                Grid.svelte
                                /components/
                                  UserCard.svelte
                                  ProductCard.svelte
                          


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

                          Это совершенно не обязательно. Просто иногда это удобнее. Например вы примере выже, /src/components/Grid/index.js просто точка для импорта компонента Grid.svelte, чтобы удобнее было импортировать:

                          import Grid from '~/components/Grid/Grid.svelte';
                          
                          vs
                          
                          import Grid from '~/components/Grid/';
                          


                          Кстати, а как в svelte с ленивой подгрузкой компонентов дела обстоят?

                          А как это вообще относится к фреймворку? Разве не любой фреймворк позволяется делать динамический импорт и значение промиса, который тот возвращает, вставлять в качестве компонента? Всю грязную работу все равно бандлер выполняет тут.
                            –1
                            Есть полезный бойлерплейт, а есть бесполезный. Бесполезный это когда ты вынужден писать кучу лишних скобок или импортировать, а потом еще регистрировать комоненты и другие сущности, и т.п.

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


                            А тут на лицо полезный бойлерплейт. Во-первых, он делает структуру приложения понятно и прозрачной.

                            Это каким образом структура приложения становится более понятной и прозрачной от того что вас лишили возможности структурировать код?


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

                            Ну вот когда будет большой (90% — что никогда), тогда и вынесете в отдельный файл. YAGNI же.


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

                            Шел 2019, казалось бы, а люди что-то там в файлах ищут.


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


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

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


                            то этот вопрос имхо лучше решить на уровне файловой системы:

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


                            А как это вообще относится к фреймворку?

                            Ну напрямую. Способ ленивого использования компонент всегда прибит к фреймворку. Как в свелте это делается? А динамические компоненты как создаются? Сам компонент в свелте как сущность — это вообще что?

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

                              Вот лично я с 2013 года импортирую и регистрирую компоненты. Сперва в рамках Ractive, потому Vue, потом Svelte 1-2. Расскажите пожалуйста о преимуществах импорта + регистрации, перед просто импортом. Интересно.

                              Это каким образом структура приложения становится более понятной и прозрачной от того что вас лишили возможности структурировать код?

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

                              Ну вот когда будет большой (90% — что никогда), тогда и вынесете в отдельный файл. YAGNI же.

                              Еще раз, мне это нужно, чтобы проект имел четкую структуру — один компонент, один файл. Без вариантов и вариаций, которые в данном случае совершенно неуместны.

                              Шел 2019, казалось бы, а люди что-то там в файлах ищут.

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

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

                              Нормальные это какие? На том же Vue, с которого началось обсуждение, и на котором мы писали с момента появления 2-ки и до сих пор, никто тоже так не делает. Идеоматический способ использовать все те же SFC. То что реакт можно превратить в помойку большая часть разработчиков реакт, с которыми я знаком, считают пагубным делом и имеют проблемы с этим на своих проектах. Не нужно придумывать из мухи слона. Для мелкого проекта, засунуть в один файл еще куда ни шло, но когда проект хоть чуть крупнее или средний — это большая ошибка.

                              Какая разница вообще, в каком что файле? Обычно файлвоая структура разработчику неинтересна. Программист не работает с файлами, он работает с программными сущностями — модулями, классами, функциями.

                              А импортируете эти сущности вы не из файлов случаем?

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

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

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

                              Совершенно не согласен. Ваше право так думать, но такие штуки как Next/Nuxt/Sapper даже конвенции роутинга возложили на файловую систему. И многих людям, включая меня, очень нравится.

                              Ну напрямую. Способ ленивого использования компонент всегда прибит к фреймворку.

                              Вы не очень видимо понимаете, что сама инициализация «ленивого» или «не ленивого» компонента, но просто динамического компонента, никак не отличаются. То есть если вы просто можете сменить компонент по условию где-то в точке монтирования, то этого достаточно для того, чтобы работала подгрузка компонентов по запросу. Поэтому, нет, сама по себе ленивая загрузка компонентов с фреймворком не связана. Либо надо формулировать не «ленивый», который подразумевает «по запросу», а «динамический», который подразумевает подстановку в рантайме.

                              Как в свелте это делается? А динамические компоненты как создаются?

                              Легче легкого:

                              <button on:click={load}>Load component</button>
                              <svelte:component this={comp} />
                              
                              <script>
                                let comp = null;
                              
                                function load() {
                                  import('./Component.svelte')
                                    .then(({ default }) => {
                                      comp = default;
                                    });
                                }
                              </script>
                              


                              Или даже просто так при рендере парента и сразу со индикацией загрузки и выводом ошибок:

                              {#await import('./Component.svelte')}
                              <p>Loading...</p>
                              {:then comp}
                              <svelte:component this={comp.default} />
                              {:catch err}
                              <p>Component loading error: {err.message}</p>
                              {/await}
                              


                              Сам компонент в свелте как сущность — это вообще что?

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

                              import Cart from '~/compoenents/Cart.svelte';
                              
                              const cart = new Cart({
                                target: document.getElementById('cart'),
                                props: { ... }
                              });
                              
                              // total sum of products in cart (computed value)
                              console.log(cart.total);
                              
                              // <button id="addBtn" value="{productId}">Add to cart</button>
                              document.getElementById('addBtn').addEventListener(e => {
                                cart.add(+e.target.value);
                              }); 
                              
                              


                                0

                                Уточнение: в реакте компонент точно так же можно создать из внешнего кода и дергать его методы, просто потребуется 1 вызов ReactDOM.render

                                  0
                                  А можно пример, чтобы быть точным? Просто я привык, что ReactDOM.render выгледит примерно так:

                                  function Cart() {
                                    ....
                                  }
                                  
                                  ReactDOM.render(<Cart />, document.getElementById('cart');
                                  

                                  Только вот что делать, если файл внешнего кода не проходит через сборщик (транспиллер), например? Как зашипить компонент React в качестве подключаемого на страницу через script-тег класса?
                                    0

                                    Вот так же:


                                    var Cart = require('Cart'); // допустим, у нас requirejs
                                    var cart = ReactDOM.render(React.createElement(Cart), document.getElementById('cart'));

                                    Разумеется, сам компонент через транспилер придётся перегнать.

                                      0
                                      А все понял, спасибо. Забыл что можно дернуть React.createElement вручную. Хотя если все перейдут на хуки и функциональные компоненты, то от этого толка будет не очень много))
                                        0

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


                                        Обычные компоненты (те, что взаимодействуют через свойства, а не через методы) тоже можно подключать, но придется вызывать ReactDOM.render для каждого изменения свойств.

                                  –2
                                  Расскажите пожалуйста о преимуществах импорта + регистрации, перед просто импортом. Интересно.

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


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

                                  Но но когда надо не в отдельный, то это менее понятно, наоборот.


                                  А импортируете эти сущности вы не из файлов случаем?

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


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

                                  То, что вы описываете, не имеет отношения к структуризации приложения. Потому что приложение — это не файлы и папки. У вас просто чрезмерно низкоуровневое мышление.


                                  Вы видимо валите все в одни файл, аля PHP начала 2000-ых.

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

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

                                    А как вы его в Vue можем прям уж «настроить»?

                                    import Nested from './Nested.vue';
                                    
                                    export default {
                                      components: { 
                                        Nested 
                                      } 
                                    };
                                    

                                    Так, что настраивать будем?

                                    Но но когда надо не в отдельный, то это менее понятно, наоборот.

                                    Просто никогда не надо.

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

                                    В JS нет модулей/неймспейсов. Вы может из ангулярщиков вообще? Раскусил вас))) Вас так послушать, раз такая штука есть только в ангуляр, то и использовать надо только его))))

                                    То, что вы описываете, не имеет отношения к структуризации приложения. Потому что приложение — это не файлы и папки. У вас просто чрезмерно низкоуровневое мышление.

                                    А у вас значит чрезмерно высокоуровневое. Есть в вашем фреймворке модули/неймспейсы (кстати модули из ангуляра вроде выпиливать собирались), навится — пользуйтесь. Вообще не понимаю, зачем представитель application framework тратит свое время на баталии в рамках ui frameworks. Вы бы вон пошли, недавно статья по Ember вышла. Это из той же ниши фреймворк, что и ангуляр.

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

                                    Все валили. PHP вообще получил такое распространение по большей части потому, что умел нативно встраиваться в HTML и первое время это всех забавляло, что мешаем в один файл сразу. Только потом когда сайты подростать стали, подумали что не очень как-то.

                                  0
                                  он вам дает полезные возможности, который у вас без импорта и регистрации нет.

                                  MAM архитектура даёт эти возможности без ручных импортов и регистраций. Так что бойлерплейт этот весьма бесполезный.


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

                                  И это очень плохо, так как поощряет бардак в репозитории. Напротив, форсирование порядка, позволяет использовать это для уменьшения бойлерплейта. В частности — избавиться от импортов и регистраций.


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

                                    0
                                    MAM архитектура даёт эти возможности без ручных импортов и регистраций.

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

                                      –2

                                      Вы вот вроде много слов написали, а смысл я так и не уловил. Вот где в $mol импорты/экспорты/регистрации/конфиги с отношениями?

                                        0

                                        Я откуда знаю? $mol же это ваш фреймворк.
                                        Вот и скажите, как мне настроить в $mol использование компонента Х в модуле Y.

                                          –2

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

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

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


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

                          +6
                          Я так и не узнал, зачем мне стоит писать меньше кода.

                          Верно, ведь больше кода = больше бананов!!!
                            +4
                            Статья-то была не об этом, почему надо писать меньше кода знает каждый программист.
                            0
                            Пример с react средний, вынести NumberInput станет аккуратней, но это так, мелочи. React это про «learn once write anywhere» и это круто, больше ни у кого нет развитой ветки native. Как у Svelte дела?

                            Пока единственный здоровый плюс Svelte для меня — маленький бандл, это классно. Но такоже даёт elm, которому куча лет и тп.
                              +2

                              Ну есть еще vue-native, flutter с dart..

                                +2

                                Силами сообщества сейчас пилится Svelte-Native, но пока не для серьёзного применения.

                                –5

                                Пример vue плохой- data может быть стрелочной функцией

                                  +10
                                      function handleChangeA(event) {
                                          setA(+event.target.value);
                                      }
                                  
                                      function handleChangeB(event) {
                                          setB(+event.target.value);
                                      }
                                  
                                      <input type="number" value={a} onChange={handleChangeA}/>
                                      <input type="number" value={b} onChange={handleChangeB}/>
                                  

                                  Не будет такого в реальном проекте.
                                  Будет
                                      import Input from '../common';
                                      ...
                                      <Input type="number" value={a} onChange={setA}/>
                                      <Input type="number" value={b} onChange={setB}/>
                                  


                                    0

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


                                    function useNumberValue(initialValue) {
                                      const [value, setValue] = useState(initialValue);
                                      return [value, event => setValue(+event.target.value)];
                                    }
                                    
                                    export default () => {
                                      const [a, handleChangeA] = useNumberValue(1);
                                      const [b, handleChangeB] = useNumberValue(2);
                                    
                                      return (
                                        <div>
                                          <input type="number" value={a} onChange={handleChangeA} />
                                          <input type="number" value={b} onChange={handleChangeB} />
                                          <p>
                                            {a} + {b} = {a + b}
                                          </p>
                                        </div>
                                      );
                                    };

                                    но это уже кому как удобнее

                                      +1

                                      Ваш useNumberValue — это очень странный хук, поскольку использовать его можно только совместно с тэгом input.

                                        0

                                        а как было бы правильно?

                                          +1

                                          Правильно было в том комментарии, на который вы отвечали.

                                        0
                                        А мне вот кстати нравится. То что это хук для конкретного элемента (input) и даже типа (number) можно нивелировать его логичным расположением в папках проекта, например, сделать файл hooks/input.js для всех хуков связанных с инпутами.
                                          0

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

                                            0

                                            Скорее наоборот, можно будет переключаться между разными UI-библиотеками (Material, Bootstrap и т.д.) не трогая код внутри хука.

                                              0

                                              Это вообще как?

                                              +2
                                              Вы бы еще написали, что-то вроде: «А вот есть придется вообще приложение переписать, то...». Мне кажется ничего нет страшного в том, что вы написали. Очевидно, что переход с инпута на что-то еще — это серьезная мера.

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

                                          0
                                          И что это координально что-то изменило? Вы спрятали реализацию handleChange внутрь общего компонента Input, но теперь внутри должна быть целая партянка преобразований для всех возможных типов input поля. Тогда уж лучше написать специализированный компонент, типа InputNumber, а не комбайн. В любом случае, написание целого компонента, там где хватило бы просто биндинга, чтобы сделать приведение типа, не выглядит отличным подходом.

                                            0
                                            Насчет NumberInput я соглашусь, хотя это вопрос вкуса. А вот то что фреймворк сам делает преобразование типа – это очень х… во. Нельзя менять общепризнаное API. Либо давайте другое имя компоненту, и я могу кликнуть по его имени и перейти к реализации. Либо его поведение компонента совпадает с описанием WHATWG/W3C, да хотя бы MDN. Почему пользователи фреймворка должны учить кастомное поведение, если разработчики фреймоворка не удосужились выучить дефолтное?
                                              0
                                              А вот то что фреймворк сам делает преобразование типа – это очень х… во. Нельзя менять общепризнаное API

                                              То есть вы знаете конкретный кейс, когда значение поля для ввода с type=number должно использоваться как строка? Хм… честно говоря я не знаю. В итоге получается, что вам приходится создавать целый компонент, чтобы просто исправить неочевидное поведение браузерной реализации импута, а зачем? Если уж не хотите пользоваться благами автоматизации и хочется писать все руками, то Svelte не запрещает вам использовать подход реакта:

                                              <input type="number" value={a} on:input={handleChangeA}>
                                              <input type="number" value={b} on:input={handleChangeB}>
                                              


                                              Пшык и проблемы нет? Был бы смысл в этом только…

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

                                              Потому что это удобно, это изначально ожидаемое поведение для type=number и это скорее бага в спецификации. Кроме того, использование 2way биндингов не только опциональное, но и отключаемое на уровне компилятора.

                                              Ну и как бы 2way биндинги не обязаны вообще следовать стандартам, потому что в стандартах их нет. Они нужны исключительно для удобства использования, а не просто для прокидывания значений как есть. Если вам нужно raw-значение, используйте ивенты как я описал выше и пишите собственное приведение типов для каждого места использования. Право ваше.
                                                0
                                                То есть вы знаете конкретный кейс, когда значение поля для ввода с type=number должно использоваться как строка?

                                                Когда оно не целое.

                                                  0
                                                  А что сложение не целых чисел в JS делается с помощью строк? Не знал: svelte.dev/repl/bb67cff2eaf0486498bb1510bc7b5fa4?version=3.3.0
                                                    0

                                                    При чем тут сложение? Вы спрашивали конкретный кейс, я вам назвал конкретный кейс. Складывать ничего не надо.
                                                    Попробуйте написать "0.5" в своем примере.
                                                    Еще у вас пишутся нули слева и сбрасывается позиция при автоматическом удалении нулей с конца.
                                                    Забаговано, короче, приемку ваш инпут не прошел.
                                                    И проблема в том, что нормальный инпут из него даже не сделать, не меня логики, которая там в потрохах защита.
                                                    Валидация с запятыми тоже, кстати, криво работает.

                                                      –1
                                                      Попробуйте написать «0.5» в своем примере.

                                                      А вы попробуйте написать 0,5 то есть так как работает input type=number. Мне вот вообще само поле не дает написать точку. Все остальное работает как и предполагается: svelte.dev/repl/bb67cff2eaf0486498bb1510bc7b5fa4?version=3.3.0

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

                                                      Здрасти, мы с вами не пишем компонент input number для всех случаев жизни, а просто получаем значение из html input в виде числа для сложения. И я не знаю кейсов, когда число нам нужно ввиде строки.
                                                        +2
                                                        А вы попробуйте написать 0,5

                                                        Мне не надо 0,5, мне надо 0.5, потому что так хочет пользователь. И выводит же 0.5 с точкой. А вводится с запятой? Это что за шизофрения с разным форматом ввода/вывода?


                                                        работает input type=number

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


                                                        Мне вот вообще само поле не дает написать точку.

                                                        Вот именно! А как сделать, чтобы давало?


                                                        Все остальное работает как и предполагается:

                                                        Нет, не работает. Стартовые нули должны удаляться (не удаляются) позиция курсора при удалении нулей на конце сбрасываться не должна (она сбрасывается), валидация запятой должна быть консистентна (она неконсистентна).


                                                        Здрасти, мы с вами не пишем компонент input number для всех случаев жизни, а просто получаем значение из html input в виде числа для сложения.

                                                        Я же вам сказал, в чем проблема. Проблема в том, что из вашего инпута нельзя сделать нормальный, человеческий инпут. Из инпута, который отдает строку — можно, а из вашего — нельзя. В этом и состоит кейс, когда "значение поля для ввода с type=number должно использоваться как строка".

                                                          –1


                                                          Мне не надо 0,5, мне надо 0.5, потому что так хочет пользователь. И выводит же 0.5 с точкой. А вводится с запятой? Это что за шизофрения с разным форматом ввода/вывода?

                                                          Это веб-стандарты, детка) HTML вводит 0,1, а js выводит 0.1 )))) Причем тут Svelte?

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

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

                                                          Вот именно! А как сделать, чтобы давало?

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

                                                          Нет, не работает. Стартовые нули должны удаляться (не удаляются) позиция курсора при удалении нулей на конце сбрасываться не должна (она сбрасывается), валидация запятой должна быть консистентна (она неконсистентна).

                                                          Типа, вы считаете правильным, что для input number можно написать число 007 и браузерный инпут спокойно примет это значение в качестве числа? Мне кажется это не нормально. Если считаете иначе, можете не юзать биндинги. Мое мнение тут не изменилось — биндинги чинят некоторые огрези реализации нативных контролов, чтобы разработчику было удобнее.

                                                          Я же вам сказал, в чем проблема. Проблема в том, что из вашего инпута нельзя сделать нормальный, человеческий инпут. Из инпута, который отдает строку — можно, а из вашего — нельзя. В этом и состоит кейс, когда «значение поля для ввода с type=number должно использоваться как строка».

                                                          У нас с вами видимо разные представления о правильном инпуте. Для меня числовой инпут дающий вводить не число — это не совсем правильный инпут))

                                                            0
                                                            Причем тут Svelte?

                                                            Svelte при том, что этот инпут — не нативный, а обертка над ним. Он не ведет себя как нативный, он ведет себя так, как написали разработчики svelte.


                                                            Это веб-стандарты, детка)

                                                            Но вы же понимаете, что пользователю до фени веб-стандарты?


                                                            Я еще раз уточню, в чем проблема — она не в том что поведение конкретно такое, кривое или нет, не важно. Оно в том, что его поменять нельзя. Именно из-за того, что у вас число вместо строки.


                                                            То есть ответ на ваш вопрос "зачем надо число возвращать в виде строки" — чтобы можно было свободно его обработать, как захочется.


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

                                                            Оно на целое число меняется, там ни запятых, ни точек. И это не важно, поймите, как вам (или мне, или разработчику свелте) кажется лучше.


                                                            У нас с вами видимо разные представления о правильном инпуте.

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

                                                              0
                                                              Svelte при том, что этот инпут — не нативный, а обертка над ним. Он не ведет себя как нативный, он ведет себя так, как написали разработчики svelte.

                                                              Это реализация биндинга такая. Может она бажит, что не исключено. В любом случае, если что-то не устраивает в нем, всегда можно использовать `on:input`.

                                                              Я еще раз уточню, в чем проблема — она не в том что поведение конкретно такое, кривое или нет, не важно. Оно в том, что его поменять нельзя. Именно из-за того, что у вас число вместо строки.

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

                                                              То есть ответ на ваш вопрос «зачем надо число возвращать в виде строки» — чтобы можно было свободно его обработать, как захочется.

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

                                                              <input type="number" value={a} on:input={e => a = +e.target.value}>
                                                              


                                                              Оно на целое число меняется, там ни запятых, ни точек. И это не важно, поймите, как вам (или мне, или разработчику свелте) кажется лучше.

                                                              А вы сами попробуйте:

                                                              <input type="number" step="0.1" bind:value={a}>
                                                              


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

                                                              А что пользователь хочет видеть решаете вы или кто?
                                                                –2
                                                                Это реализация биндинга такая.

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


                                                                Можно не использовать биндинг и написать любое свое поведение.

                                                                То есть свой инпут писать? Отличное предложение.


                                                                А вы сами попробуйте:

                                                                А, ну если степ выставить то да.


                                                                А что пользователь хочет видеть решаете вы или кто?

                                                                Решает, очевидно, сам пользователь.

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

                                                                  Так почему нельзя то? Не нравится как реализован автоматический 2way биндинг? Нужна строка или какие-то дополнителные манипуляции? Не используйте! Svelte лишь предоставляет дополнительный, встроенный и простой механизм, а уж сделать в лоб, как в реакт, всегда можно:

                                                                  <input type="number" value={a} on:input={handleChangeA}>
                                                                  


                                                                  То есть свой инпут писать? Отличное предложение.

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

                                                                  Решает, очевидно, сам пользователь.

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

                                                                  React:
                                                                  1) Если ли возможность отловить изменением поля и созранить значение в стейт вручную? ДА
                                                                  2) Есть ли механизм 2way биндинга с автоматическим приведением типа в зависимости от типа поля? НЕТ

                                                                  Svelte:
                                                                  1) Если ли возможность отловить изменением поля и созранить значение в стейт вручную? ДА
                                                                  2) Есть ли механизм 2way биндинга с автоматическим приведением типа в зависимости от типа поля? ДА

                                                                  То есть Svelte просто дает вам больше возможностей, ничего при этом не отнимая. Надо пользуйтесь, в этой задаче автор решил что этого будет достаточно. Надо что-то другое — используйте другой подход. Проблемы же нет!

                                                                    –2
                                                                    Не используйте!

                                                                    Не использовать что, svelte? :)


                                                                    Почему свой то? Просто написать как в реакт.

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


                                                                    1) Если ли возможность отловить изменением поля и созранить значение в стейт вручную? ДА

                                                                    Так нет. Надо писать руками свой биндинг. Или, погодите, вот это вот: on:input={handleChangeA}, это биндинг свелте, а не нативный?
                                                                    Ну тогда это вообще нк, в одностороннем биндинге у вас компонент отдает строку, а в двухстороннем тот же компонент отдает число :tt:
                                                                    В какой вселенной это считается нормальным?

                                                                      +1
                                                                      Не использовать что, svelte? :)

                                                                      Конкретно вам именно это и рекомендую! Мучайтесь дальше))

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

                                                                      Это в реакт нельзя, потому что там просто нет такого биндинга. Читайте код)) Говорят можно, а вы как Фома.

                                                                      Так нет. Надо писать руками свой биндинг. Или, погодите, вот это вот: on:input={handleChangeA}, это биндинг свелте, а не нативный?
                                                                      Ну тогда это вообще нк, в одностороннем биндинге у вас компонент отдает строку, а в двухстороннем тот же компонент отдает число :tt:
                                                                      В какой вселенной это считается нормальным?

                                                                      Это нормально, потому что это вообще не биндинг, если не видите. Это event handler, ровно такой же как в реакт. А если быть точным, это директива браузерного события input на элементе и работает так, как вы ожидаете от браузера.

                                                                      В Svelte 1а и 2х биндинги работают так:

                                                                      <!-- 1way - only write -->
                                                                      <input value={a}>
                                                                      
                                                                      <!-- 2way - write&read -->
                                                                      <input bind:value={a}>
                                                                      
                                                                      <!-- event directive with 1way - React-like -->
                                                                      <input value={a} on:input={handler}>
                                                                      

                                                                      3-й раз написал одно и тоже. Надеюсь в этот раз до вас наконец-то дойдет.

                                                                        –3
                                                                        Это в реакт нельзя, потому что там просто нет такого биндинга. Читайте код))

                                                                        В каком смысле нет? Я пишу onChange={handleChange} — вот это биндинг, который мне реакт предоставляет.


                                                                        Это нормально, потому что это вообще не биндинг, если не видите. Это event handler, ровно такой же как в реакт.

                                                                        Так еще раз — в реакт есть готовый биндинг, а в свелте можна_сделать при помощи нативных средств, так? Ну то что можно выкинуть любой фреймворк и руками написать что угодно — не секрет.

                                                                          +2
                                                                          Я пишу onChange={handleChange} — вот это биндинг, который мне реакт предоставляет.
                                                                          — это не биндинг, это эвент-хендлер, и биндинг ещё надо написать в обработчике.
                                                  +2
                                                  вы знаете конкретный кейс, когда значение поля для ввода с type=number должно использоваться как строка?

                                                  Чтобы написать "e" - не является валидным значением, а не "undefined" - не является валидным значением.

                                                    0
                                                    А зачем это писать, если можно просто не давать вводить не валидные значения? Например, когда я в интернетах вижу поле для ввода телефона и пытаюсть туда текст вбить, а он не вводится, для меня это выглядит как очевидное поведение для поля телефон. Я сразу понимаю, что «насрать» в поле не получится.
                                                      –2

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

                                                        –1
                                                        А зачем это писать, если можно просто не давать вводить не валидные значения?

                                                        Ну вот пустая строка — это невалидное значение и ее можно написать. Если бы вы сразу инициализировали компонент какой-то непустой строкой ('0' например) и не давали возможности стереть все до пустой — другой разговор. Это правда, тоже весьма неудобное поведение.

                                              –11
                                              Сначала, версия Svelte:

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


                                              1. Надо управлять входными данными.
                                              2. Надо получать результаты.
                                              3. Надо стилизовать каждый дом-элемент.
                                              4. Надо иметь возможность кастомизировать стили.
                                              5. Надо прикручивать e2e тесты.
                                              6. Надо собирать аналитику по использованию.

                                              В результате код обрастает тем самым шумом, с которым боролись:


                                              <script>
                                              
                                                import Number from './Number.svelte';
                                              
                                                export let name = ''
                                                export let prefix = ''
                                                export let a = 1;
                                                export let b = 2;
                                                export let style;
                                              
                                                let id = prefix + '.' + name
                                              
                                                export let res;
                                                $: res = a + b;
                                              
                                              </script>
                                              
                                              <Number prefix={id} name="a" bind:value={a} style={style.a} />
                                              +
                                              <Number prefix={id} name="b" bind:value={b} style={style.b} />
                                              =
                                              <span id={ id + '.' + 'res' } class="res" style={style.res}>{res}</span>

                                              И это ещё без асинхронного вычисления значения и без обработки ошибок, без которого Svelte показывает просто белый экран.


                                              Ну и для сравнения, вот как выглядит почти полное отсутствие шума на самом деле:


                                              $my_form $mol_view
                                                  sub /
                                                      <= First $mol_number
                                                          value?v <=> first?v 1
                                                      \+
                                                      <= Second $mol_number
                                                          value?v <=> second?v 1
                                                      \=
                                                      <= Result $mol_view
                                                          sub /
                                                              <= result \

                                              namespace $.$$ {
                                                  export class $my_form extends $.$my_form {
                                              
                                                      result() {
                                                          return this.first() + this.second()
                                                      }
                                              
                                                  }
                                              }
                                                +22

                                                Тут на китайском? Я никогда не писал на svelte и reacrt, но их код я понял сразу, не говоря уже о vue. Но ваши примеры видел раз 10 на хабре, но так и не понял, что эта куча символов значит. \= и так далее

                                                  –1

                                                  Возможно лаконичность синтаксиса замотивирует вас почитать документацию: https://github.com/eigenmethod/mol/tree/master/view#viewtree

                                                    0

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

                                                      –3

                                                      Проще всего понять суть, сравнивая исходный и сгенерированный код в песочнице.

                                                        +3

                                                        если честно не сильно проще, я даже не понимаю что делает пример в песочнице и зачем он нужен

                                                  +5

                                                  И куда подевались prefix, id и style, которые вы добавили в код на svelte, но их не видно в tree?


                                                  Для полноты сравнения нужно было наверное показать еще имплементацию First, Second и Result.

                                                    –1
                                                    но их не видно в tree?

                                                    О том и речь, что во view.tree это всё не надо делать вручную. Автоматика-с.


                                                    нужно было наверное показать еще имплементацию First, Second и Result.

                                                    Вообще-то они показаны. Я привёл полностью работоспособный код компонента. Вы можете скопипастить его в my/form/form.view.tree и my/form/form.view.ts и далее использовать.

                                                      +1

                                                      В конечном html у нас два тэга input для ввода и один span для вывода. В исходном коде они никак не фигурируют.


                                                      Или хотите сказать, что "<=>" обозначает input, а "<=" – span?

                                                        –2
                                                        В конечном html

                                                        Конечный — всё-таки DOM. HTML — это просто один из способов его сериализации.


                                                        Или хотите сказать, что "<=>" обозначает input, а "<=" – span?

                                                        Нет, это двусторонний и односторонний биндинги свойств.


                                                        <= First $mol_number
                                                                    value?v <=> first?v 1

                                                        Создать компонент $mol_number и назвать его First, привязать его значение value к нашему значению first, и вывести его.

                                                          0

                                                          Тогда для честного сравнения нужно учитывать еще и сериализатор.


                                                          Для React я тоже могу написать написать свой рендерер на замену react-dom, на котором пример тоже получится в 3 строчки, но объективным сравнением это никак не будет.

                                                            –2
                                                            Тогда для честного сравнения нужно учитывать еще и сериализатор.

                                                            Он-то тут каким боком?


                                                            я тоже могу написать

                                                            Так напишите и будем сравнивать.

                                                        0
                                                        О том и речь, что во view.tree это всё не надо делать вручную. Автоматика-с.

                                                        При всем уважении, автоматика — это когда не нужно view-компоненты создавать самому, а если для каждого куска на экране все так же нужно создавать и заполнять вручную файл, то его синтаксис по сути ни на что не влияет.
                                                      +14
                                                      Ну и для сравнения, вот как выглядит почти полное отсутствие шума на самом деле:

                                                      $my_form $mol_view
                                                          sub /
                                                              <= First $mol_number
                                                                  value?v <=> first?v 1
                                                              \+
                                                              <= Second $mol_number
                                                                  value?v <=> second?v 1
                                                              \=
                                                              <= Result $mol_view
                                                                  sub /
                                                                      <= result

                                                      Для стороннего наблюдателя, который не восхищен безусловно своим дитятком, так выглядит сплошной белый шум.
                                                        +4
                                                        $my_form $mol_view
                                                            sub /
                                                                <= First $mol_number
                                                                    value?v <=> first?v 1
                                                                \+
                                                                <= Second $mol_number
                                                                    value?v <=> second?v 1
                                                                \=
                                                                <= Result $mol_view
                                                                    sub /
                                                                        <= result \

                                                        Это что-то на Хаскелле?
                                                          +4

                                                          Не обижайте Хаскель!

                                                            +1

                                                            Я почему-то подумал, что это гибрид хаскеля и постскрипта.

                                                            0

                                                            Дмитрий, на что вы ориентировались при разработке UI mol компонентов. Grid, flexbox...?

                                                              0

                                                              Там флексбоксы в основном используются.

                                                              +2
                                                              Понять бы еще зачем вы все это понаписали. Что такое prefix? Зачем он одинаковый для обоих инпутов? Пример на $mol вообще не содержит этих вещей. Возможно они сокрыты внутри реализации $mol_number, но тогда нужно показать и его реализацию, кроме того совершенно не видно использования. Вижу привязки, но не вижу кто генерирует префиксы и стили и как они попадают внутрь $mol_number. Если это делается как-то за ширмой и не явно, то это скорее минус. Неявно можно и в Svelte, только надо ли?

                                                              Опять же, вы тут используете несколько готовых компонентов $mol ($my_form, $mol_view, $mol_number), не представляете детали их реализации, а потом говорите «смотрите!!! а на Svelte реализация этого с нуля будет уже не в 3 строчки, а в 10 строк». Хм, ну ладно. Не уверен, что это звучит очень круто и убедительно… Скорее уж наоборот)
                                                                –1
                                                                Понять бы еще зачем вы все это понаписали.

                                                                Я же написал 6 пунктов для которых всё это нужно.


                                                                Что такое prefix? Зачем он одинаковый для обоих инпутов?

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


                                                                Пример на $mol вообще не содержит этих вещей.

                                                                Потому, что фреймворк делает это всё самостоятельно, а не требует писать бойлерплейт.


                                                                Возможно они сокрыты внутри реализации $mol_number

                                                                Они сокрыты в $mol_view, от которого наследуются вообще все компоненты. Это тот самый рантайм, с которым "борется" Svelte.


                                                                Неявно можно и в Svelte

                                                                Попробуйте реализовать.


                                                                Опять же, вы тут используете несколько готовых компонентов $mol ($my_form, $mol_view, $mol_number), не представляете детали их реализации

                                                                $my_form — компонент, который тут собственно и создаётся.
                                                                $mol_number — стандартный компонент. Реализацию Number для Svelte я тоже не привёл, так что всё честно.
                                                                $mol_view — тот самый рантайм, которого в Svelte нет, и который прячет от программиста львиную долю бойлерплейта.

                                                                  0
                                                                  Я же написал 6 пунктов для которых всё это нужно.

                                                                  Это очень абстракные 6 пунктов, но я попробую их прокомментировать:

                                                                  Надо управлять входными данными.

                                                                  Происходит фактически также как во всех популярных UI фреймворках, типа React и Vue. Кроме «props down, events up», можно еще «2way binding» на пропсы компонентов при желании. Пропсы и публичные методы очень четко отделены от приватного стейта и функций. Реактивные декларации помогают делать любой пре-форматинг входящих значений. Для расшаривания стейта между компонентами есть очень реактивные сторы на обсерверабл с очень удобным «сахаром» компилятора, который возволяет работать с ними в синхронной манере.

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

                                                                  Надо получать результаты.

                                                                  «Забрать» значения из компонента можно через события или двойное связывание.

                                                                  Надо стилизовать каждый дом-элемент.
                                                                  Надо иметь возможность кастомизировать стили.

                                                                  Из коробки работают как изолированные стили, так и глобальные. Можно прокидывать стили через пропсы. Любой доступныей функционал CSS и даже CSS-in-JS. Кроме того, можно при большом желании точечно перегружать стили подкомпонентов из родительского, без прокидывания через пропсы, но лучше это использовать только для leaf-компонентов.

                                                                  Надо прикручивать e2e тесты.

                                                                  Прикручивайте, причем тут фреймворк? В стандартной поставке Sapper, например, идет Cypress.

                                                                  Надо собирать аналитику по использованию.

                                                                  Тоже самое. Прикручивается за 2 минуты с помощью пары хелперов.

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

                                                                  Зачем тогда его прокидывать каждому компоненту вручную? Я бы сделал общий экшн и просто подписывал его туда куда надо:

                                                                  <div use:uid>
                                                                  ...
                                                                  </div>
                                                                  
                                                                  <script>
                                                                    import uid from '~/actions/uid.js';
                                                                  </script>
                                                                  

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

                                                                  Потому, что фреймворк делает это всё самостоятельно, а не требует писать бойлерплейт.

                                                                  То что в $mol это уже идет из коробки, не является плюсом для меня. К тому же я не знаю как это реализовано, может мне это не подходит. А если мне вообще это не нужно? Как это выпилить их вашей коробки?

                                                                  Они сокрыты в $mol_view, от которого наследуются вообще все компоненты. Это тот самый рантайм, с которым «борется» Svelte.

                                                                  Вот именно, он нам не нужен. Подобный рантайм, с которым Svelte борется, мешает делать компоненты по настоящему независимыми. Раз все компоненты наследуются от $mol_view, а он в себе содержит много встроенных возможностей, как мне их оттуда выпилить, если мне они не нужны или если мне нужна какая-то собственная реализация?

                                                                  $my_form — компонент, который тут собственно и создаётся.

                                                                  Сорян, там у вас черт ногу сломит. Имел ввиду конечно же $.$my_form от которого он наследуется. Думаю имеет смысл привести реализацию этого компонента. То что он «стандартный» не считается.

                                                                  Попробуйте реализовать.

                                                                  Реализацию Number для Svelte я тоже не привёл, так что всё честно.

                                                                  Так давайте исправим это:

                                                                  Input.svelte
                                                                  <div use:uid={{id}} class:floating>
                                                                    <input 
                                                                      use:imask={mask} 
                                                                      {value} 
                                                                      {id} 
                                                                      {...attrs} 
                                                                      on:accept={e => value = e.target.value}
                                                                      on:focus={e => active = true} 
                                                                      on:blur={e => active = false} 
                                                                    >
                                                                    {#if label}
                                                                    <label class:active for={id}>{label}</label>
                                                                    {/if}
                                                                  </div>
                                                                  
                                                                  <script>
                                                                    import imask from 'svelte-imask';
                                                                    import uid from '~/actions/uid';
                                                                  
                                                                    let active = false,
                                                                        floating = true,
                                                                        label = '',
                                                                        value,
                                                                        mask,
                                                                        attrs,
                                                                        id;
                                                                  
                                                                    $: {
                                                                      let { id, mask, label, floating, value ...rest } = $$props;
                                                                      attrs = rest;
                                                                    }
                                                                  
                                                                    export {
                                                                      floating,
                                                                      label,
                                                                      value,
                                                                      mask,
                                                                      id
                                                                    };
                                                                  </script>
                                                                  
                                                                  <style>
                                                                    div { ... }
                                                                    input { ... }
                                                                    label { ... }
                                                                    label.active { ... }
                                                                    .floating label { ... }
                                                                  </style>
                                                                  


                                                                  Это компонент поля, который поддерживает все возможности html input, кроме того поддерживает маскинг но основе imask (все его опции), можно устанавливать лейбл, как обычный, так и floating (аля Material Design). Пользуемся как вы написали, только без prefix.

                                                                  Теперь давайте посмотрим на реализацию такого же компонента, только на $mol. Только полную, со стилями, с поддержикой всех типов инпутов, с интеграцией с 3rd-party решением (imask) и т.д.

                                                                  $mol_view — тот самый рантайм, которого в Svelte нет, и который прячет от программиста львиную долю бойлерплейта.

                                                                  Который никому как раз и не нужен, потому что всем нужны независимые микро-компоненты, которые можно собирать в разной композиции.
                                                                    –2
                                                                    я попробую их прокомментировать

                                                                    К чему весь этот маркетинг с очень частым употреблением слова "очень"? Я же привёл пример кода, который получится, после реализации этой функциональности. Можете сократить — дерзайте. Не в ущерб функциональности только.


                                                                    ибо не нравится оно просто

                                                                    Устроили тут детский сад.


                                                                    Прикручивайте, причем тут фреймворк?

                                                                    А вы попишите e2e тесты, чтобы прочувствовать всю боль их поддержки, когда после очередного коммита, тесты отваливаются, потому что не находят нужного элемента или находят сразу несколько и берут первый попавшийся, или просто находят не тот элемент, но который по счастливой случайности сматчился на ваш селектор. Собственно, на главной же странице cypress можно видеть селектор по значению атрибута src у картинки. Изменили ссылку — сломались все тесты, в которых эта картинка участвовала. Вывели ещё куда-то эту картинку — получайте зелёные тесты для сломанной функциональности. В какой-то момент автотестировщикам задалбывает тратить большую часть своего рабочего времени на починку тестов. Они приходят к программистам и просят их ставить элементам уникальные идентификаторы. И тут начинается веселье с префиксами, когда один компонент есть на странице в нескольких экземплярах. В какой-то момент устаёшь писать бойлерплейт и начинаешь задумываться, что неплохо было бы автоматизировать генерацию идентификаторов. Но уже поздно, ибо на старте проекта выбрали инструмент, в котором это не автоматизировать, так как посчитали тогда, что "вам это не нужно".


                                                                    Прикручивается за 2 минуты с помощью пары хелперов.

                                                                    За 2 минуты аналитика прикручивается при автогенерации уникальных человекопонятных идентификаторов. А без них вам придётся во все вьюшки руками добавлять идентификаторы, имея всё те же проблемы, что и с тестами. С той лишь разницей, что в случае ошибки, у вас будет мусор в статистике, который вы не сможете исправить задним числом. И как с любой ручной работой ошибок будет много. И очень весело узнавать, что статистика за последние пол года накрылась медным тазом, когда ошибки всё же обнаруживаются.


                                                                    Я бы сделал общий экшн

                                                                    Далее следует код, который не понятно что и не понятно как делает. И после этого вы ещё предъявляете какие-то претензии к $mol, где кроме классов и реактивных свойств нет абсолютно ничего, ибо этих двух идиом достаточно для описания интерфейсов любой сложности.


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

                                                                    На основе чего он будет их генерить? Откуда он возьмёт информацию о семантике?


                                                                    А если мне вообще это не нужно?

                                                                    1. На самом деле нужно.
                                                                    2. Оно в любом случае не мешает.

                                                                    если мне нужна какая-то собственная реализация?

                                                                    Берёте и пилите свою реализацию, к $mol_view вас никто гвоздями не прибивает. В отличие от того же Svelte, где прикладной программист вообще не контролирует, как будет рендериться компонент, какой использовать шаблонизатор и тп.


                                                                    Имел ввиду конечно же $.$my_form от которого он наследуется. Думаю имеет смысл привести реализацию этого компонента. То что он «стандартный» не считается.

                                                                    Этот класс определён во view.tree
                                                                    $my_form $mol_view
                                                                        sub /
                                                                            <= First $mol_number
                                                                                value?v <=> first?v 1
                                                                            \+
                                                                            <= Second $mol_number
                                                                                value?v <=> second?v 1
                                                                            \=
                                                                            <= Result $mol_view
                                                                                sub /
                                                                                    <= result \

                                                                    Так давайте исправим это

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


                                                                    всем нужны независимые микро-компоненты, которые можно собирать в разной композиции

                                                                    TodoMVC на Svelte — 8кб, на $mol — 15. Не большая разница. При этом для последнего вообще не ставилось задачи минимизировать размер бандла, ибо бандлы и так небольшими получаются.

                                                                      +1
                                                                      К чему весь этот маркетинг с очень частым употреблением слова «очень»? Я же привёл пример кода, который получится, после реализации этой функциональности. Можете сократить — дерзайте. Не в ущерб функциональности только.

                                                                      Вы привели пример кода для реализации этой функциональности с нуля и сравнили с реализацией на готовых компонентах. Если строить разговор так, тогда реализация будет такой:

                                                                      <Number bind:value={a} />
                                                                      +
                                                                      <Number bind:value={b} />
                                                                      =
                                                                      <span use:uid>{result}</span>
                                                                      
                                                                      <script>
                                                                        import uid from '~/actions/uid';
                                                                        import Number from '~/components/Number.svelte';
                                                                      
                                                                        export let first = 1,
                                                                            second = 1,
                                                                            result;
                                                                      
                                                                        $: result = a + b;
                                                                      </script>
                                                                      

                                                                      Коротко, но главное хотя бы понятно, что вообще происходит, а не просто набор букаф.

                                                                      Устроили тут детский сад.

                                                                      Говорит человек, который пытается присунуть свой «грязный» $mol во все статьи до которых он только дотягивается.

                                                                      Они приходят к программистам и просят их ставить элементам уникальные идентификаторы. И тут начинается веселье с префиксами, когда один компонент есть на странице в нескольких экземплярах. В какой-то момент устаёшь писать бойлерплейт и начинаешь задумываться, что неплохо было бы автоматизировать генерацию идентификаторов. Но уже поздно, ибо на старте проекта выбрали инструмент, в котором это не автоматизировать, так как посчитали тогда, что «вам это не нужно».


                                                                      За 2 минуты аналитика прикручивается при автогенерации уникальных человекопонятных идентификаторов.

                                                                      Все это верно, но причем тут UI фреймворк, если это можно организовать сверху? Вы любитель коробочных решений, это уже все поняли. Право ваше конечно, но может хватит трясти перед всеми своим $mol'ом, как эксгибиционист?

                                                                      Далее следует код, который не понятно что и не понятно как делает. И после этого вы ещё предъявляете какие-то претензии к $mol, где кроме классов и реактивных свойств нет абсолютно ничего, ибо этих двух идиом достаточно для описания интерфейсов любой сложности.

                                                                      Так я как раз и поступил как вы. Использовал некое готовое решение, которое написали для задачи и показал как его можно применить к конкретному элементу. У вас внутри $mol же наверное тоже какой-то код написан. Будем считать, что внутри экшена написан такой же код.

                                                                      На основе чего он будет их генерить? Откуда он возьмёт информацию о семантике?

                                                                      Откройте уже для себя такие штуки как finder и аналоги. И живите как нормальные люди.

                                                                      На самом деле нужно.
                                                                      Оно в любом случае не мешает.

                                                                      Не нужно. Лишнее всегда мешает, а я вижу в $mol много всего лишнего сейчас. Как исправите, приходите опять, посмотрим, подумаем. Пока нам это не нужно, спасибо, коммивояжер вы наш))) «Не хотите ли попробовать немного $mol?» )))))

                                                                      Берёте и пилите свою реализацию, к $mol_view вас никто гвоздями не прибивает.

                                                                      Как это не прибивает? Говорили же сами, что все компоненты от него наследуются, так? Фичи эти реализованы внутри него видимо и выпилить их нельзя, так? Получается вы советуете мне дублировать функционал и весь дубляж еще и в бандл тянуть? Спасибо, не надо.

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

                                                                      В $mol я не просто не контролирую что-то, я даже не понимаю как этот самый treeview связан с шаблоном и html вообще. Понятия не имею как понять, что вот эта хень:

                                                                      <= Result $mol_view
                                                                                  sub /
                                                                                      <= result \
                                                                      


                                                                      будет эквивалентна:

                                                                      =
                                                                      <span id={ id + '.' + 'res' } class="res" style={style.res}>{res}</span>
                                                                      


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

                                                                      Кроме того, в Svelte я точно знаю как будет рендериться компонент, потому что могу за пару минут прочитать ВЕСЬ его код. А чтобы понять что там твориться в $mol, с его вечно фантанирующими эксепшенами, мне еще нужно будет продебажить, что тоже не очень просто, как я понял. Как кстати дебажить TreeView? Есть там сорсмапы или еще что-то?

                                                                      Этот класс определён во view.tree

                                                                      Честно признаюсь, я ничего не понимаю в вашем коде. Вообще. Как и все тут, но мне кажется что вот это должно означать, что некий класс $my_form наследутеся от другого класса $.$my_form.
                                                                      export class $my_form extends $.$my_form
                                                                      

                                                                      Если он это наследуется от TreeView, то все еще хуже чем я думал.

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

                                                                      Мне сложно подменить предмет обсуждения, потому что его нет. Вы прибежали, навязали свою задачу, которая видимо хорошо ложиться на то, что у вас реализовано внутри готовых $mol компонентов. Показали какой-то никому не понятный код, который не понятно что делает и как работает. Дальше показали код на Svelte, так как вы его понимаете и сделали какой-то вывод. При этом никто не увидел реализацию того, о чем вы говорите, потому что оно где-то там внутри, как суслик, которого никто не видит, а он есть. Да и код, который вы представили для Svelte, учитывая что это код с нуля, выглядит весьма не плохо, если чуть причесать.

                                                                      Делаем вывод, раз на Svelte это так просто реализуется, $mol и его $mol_view нахер не нужен. Если хотите продолжать диалог именно в практической плоскости, сперва давайте реализацию аналога Input.svelte из предыдущего комментария. Будем тогда припарировать $mol на тех задачах, которые близки мне.

                                                                      TodoMVC на Svelte — 8кб, на $mol — 15. Не большая разница. При этом для последнего вообще не ставилось задачи минимизировать размер бандла, ибо бандлы и так небольшими получаются.

                                                                      Во-первых, не 8Кб, а 3.5Кб, если вы конечно про gzip (а зачем какой-то иной размер обсуждать?). Ждем тогда еще когда вы наконец-то закончите с этим. За год видимо не смогли осилить.

                                                                        –1
                                                                        Будем считать, что внутри экшена написан такой же код.

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


                                                                        Говорили же сами, что все компоненты от него наследуются, так?

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


                                                                        Получается вы советуете мне дублировать функционал

                                                                        $mol — микромодульный конструктор, ничего дублировать не надо.


                                                                        я даже не понимаю как этот самый treeview связан с шаблоном и html вообще.

                                                                        С опытом, я надеюсь, вы отучитесь думать в терминах HTML и начнёте думать в терминах компонент и их композиции.


                                                                        Как кстати дебажить TreeView? Есть там сорсмапы или еще что-то?

                                                                        Из него генерирует тайпскриптовый класс. Читать и дебажить его вы можете как угодно.


                                                                        Честно признаюсь, я ничего не понимаю в вашем коде. Вообще.

                                                                        Возможно потому, что:


                                                                        честно признаться и не сильно интересно.

                                                                        Кому было интересно — разобрались и прониклись идеями.


                                                                        Если он это наследуется от TreeView, то все еще хуже чем я думал.

                                                                        Обычное такое опциональное переопределение.

                                                                          0
                                                                          Так напишите этот код. Спойлер — ничего путного не получится.

                                                                          Типа вы смогли написать, а никто больше не сможет? ))) Знал что ваша самооценка на высоте, но так чтобы пробивать небесный свод…

                                                                          И приведённый в пример finder — та ещё хрень, генерирующая хрупкие селекторы.

                                                                          Думаю вы его не пробовали. Пока с ним проблем не было особых, но если вы знаете кейс, тогда был бы разговор.

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

                                                                          То есть единственный варинант выпилить всю ту хрень, которую вы напилили в $mol_view — это отказаться от всех готовых компонентов существующих под $mol? Да уж, все дела.

                                                                          $mol — микромодульный конструктор, ничего дублировать не надо.

                                                                          Как это, беру компонент $mol_number, который наследуется от $mol_view, пишу генерацию уникальный селекторов сверху как мне надо и получаю дублирование данного функционала в бандле. Разве нет так? Никакая микромодульность тут не поможет.

                                                                          С опытом, я надеюсь, вы отучитесь думать в терминах HTML и начнёте думать в терминах компонент и их композиции.

                                                                          Судя по степени интереса к $mol, популярности ваших статей и комментариев, делаю вывод, что вы у нас тут один такой весь опытный, просто капец)))

                                                                          Лично мне html и композиция компонентов на его основе, при всех минусах, нравится значительно больше чем ваш treeview. Можете хоть треснуть)

                                                                          Из него генерирует тайпскриптовый класс. Читать и дебажить его вы можете как угодно.

                                                                          То есть я пишу вот эту хрень, а дебажить буду то, чего я в глаза не видел, то есть какой-то TS класс, который за меня сгенерировали? Получается я должен еще разбираться, как именно мой TreeView превращается в TS? Гадость какая.
                                                                          В Svelte я почему-то дебажу именно тот код, который я пишу.

                                                                          Возможно потому, что

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

                                                                          Кому было интересно — разобрались и прониклись идеями.

                                                                          А что кто-то еще на этом пишет? Сколько там, человек 10 небось уже есть? Ну ваще прогресс конечно, аж 13 контрибуторов, 2 из которых это вы (накрутка?) и уже 211 звездочек. Ну и популярностью ваших статей/выступлений/комментариев. Мир так устроен, что в любой социальной среде, всегда есть группа маргиналов, склонных к мазахизму.

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

                                                                          p/s 212 звездочек, чтобы вам не обидно было. Успехов!
                                                                            –3

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

                                                                              0
                                                                              Прибежал, потряс перед всеми своим $mol’ом, ничего нового и интересного не рассказал. Попросили код показать, не показал. Рассказал про какую-то внутреннюю магию, которую никто повторить якобы не сможет. Кроме общих слов, никакой конкретики. Одна демагогия. По вашему все это не в стиле школоло? Собственно, часто приходится опускаться до уровня собеседника. Вот и мне тоже.

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

                                                                              Несмотря на это, специалист вы хороший, не пропадёте. А вот $mol, к сожалению для вас, совершенно точно не взлетит! Если же я ошибаюсь и в будущем он наберёт популярность, хотя бы на уровне Svelte, то я первым твитну о нем и признаю свои ошибки. Обещаю вам.
                                                                                –1

                                                                                Это тоже самое что обратиться к кому нибудь из толпы. Завязывайте типа там. Из толпы никто не будет подниматься никуда. Потому что им комфортно именно в толпе. Элита должна вести диалог с элитой или моноложить. Иначе заминусуют. Так было с Потапенко, получавшего вне хабра аварды, а на хабре не снискавшего признания. Но с вами всё не так. Дмитрий, вы безусловно нетривиальный разработчик. Чтобы продвигать $mol нужна песочница с разнообразными примерами — пресловутой "конкретикой" и 24 часовая поддержка для стартующих в мир $mol. Как то так… $mol безусловно это средство автоматизации нового левела. Но зачем кому-то что-то автоматизировать когда можно руками… $mol обвиняют а антидекларативности. Лопни мои глаза. Чем же он антидекларативен, если даже на скобках сэкономили)}). Вот скобки действительно антидекларативны, а в tree практически каждый тег несет смысловую нагрузку.
                                                                                Если вы ручками никогда не писали парсеры для AST, то и не поймете почему tree выглядит так а не по другому. У $mol есть недостатки. В прямом смысле слова. Как по мне в нем недостает самосборки на уровне объектов и xpath — like запросов для описания сценария создания приложения. Убежден, что сценарии должны выглядеть как совокупность таких запросов. Другим способами, например, jquery style запросами будет проблематично достичь полной автоматизации.

                                                                                  0

                                                                                  А что там за история с Потапенко?

                                                                +4

                                                                Это все преимущества? Не увидел ни одной весомой причины, почему я должен с Vue перейти на это

                                                                  0
                                                                  Можете попробовать почитать и другие статья про Svelte, но в целом, если вас все устраивает во Vue, тогда зачем переходить? Тут же вам не киноа вместо гречки предлагают.
                                                                  +7
                                                                  Сразу скажу, я не против Svelte. Но в статье я прям нашел несколько странных для меня моментов.
                                                                  Кроме этого, мы должны помнить, что необходимо принудительно привести строковое значение в числовое с помощью оператора +, иначе 2 + 2 будет равно 22 вместо 4.

                                                                  Кажется, явное всегда лучше. Тот факт, что в Svelte есть неявное приведение string к number в случае input type number нужно держать в голове. То есть, разбирая код на Svelte нужно потратить гораздо больше усилий мозга, нежели чем в явных решениях других ребят, что вы привели в статье. Это я про фразу
                                                                  Поэтому, когда вы читаете такой код, вам придётся приложить гораздо больше усилий, чтобы понять замысел автора.


                                                                  И в целом, читая доку по Svelte, лично у меня часто возникала мысль, блин, еще и это придется помнить. То есть кода пишем мало, да. Зато в голове теперь весь «рантайм» Svelte загрузить придется. Не спорю, с тем же React придется сделать тоже самое, но там этого «рантайма» куда меньше.
                                                                    +1
                                                                    Тот факт, что в Svelte есть неявное приведение string к number в случае input type number нужно держать в голове. То есть, разбирая код на Svelte нужно потратить гораздо больше усилий мозга

                                                                    Справедливости ради, это то, что называется expected result, а значит, если все (или правильнее сказать, если движок JS в браузере) будут возвращать данные в том же типе, что и указан в инпуте — все быстро привыкнут к "правильному, ожидаемому" поведению и проблем не будет.


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

                                                                      +3
                                                                      Немного про expected result: каков будет expected result для инуптов с type'ом tel или datetime. Для tel еще ладно, string даже норм. А вот для datetime можно и Date сделать, как expected result, дату же выбираем.

                                                                      И немного про сам Svelte, но это уже ответ не вам, а скорее к автору статьи
                                                                      Кстати, про input type=«number». Если запустить пример из статьи и стереть значение из input'а, мы получим замечательный результат: undefined + 2 = NaN.
                                                                        0
                                                                        Если запустить пример из статьи и стереть значение из input'а, мы получим замечательный результат: undefined + 2 = NaN.

                                                                        Вызываем в тред PaulMaly, он расскажет, как правильно.

                                                                          0


                                                                          Короткий ответ — das ist javascript)))

                                                                          И все же интересно было бы узнать, какого поведения по-умолчанию вы ожидаете? приведение undefined к 0? Если такое и надо делать, то для какой-то конкретной задачи, то есть в userland, а не на уровне фреймворка:

                                                                          $: sum = (a || 0) + (b || 0);
                                                                          

                                                                            0
                                                                            Если такое и надо делать, то для какой-то конкретной задачи, то есть в userland, а не на уровне фреймворка

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

                                                                              0
                                                                              Я бы с вами согласился, если бы был какой-то идеоматический способ конвертировать undefined в number. В реакт это работает как вам кажется логично, потому что +'' === 0, верное ли это приведение? Имхо нет. Вангую что при таком подходе где-нибудь в районе банковской сферы, можно нарваться на серьезные экономические последствия.

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

                                                                              export function toNumber(value) {
                                                                                return value === '' ? undefined : +value;
                                                                              }
                                                                              

                                                                              Почему-то мне кажется что у автора были причины сделать так. И тут встает вопрос, раз этот код имеет смысл и сделано так специально, возможно чтобы избежать каких-то более серьезных проблем, получается что в реакт примере мы должны делать что-то подобное:

                                                                              import toNumber from 'lodash.tonumber';
                                                                              ...
                                                                                  function handleChangeA(event) {
                                                                                      setA(toNumber(event.target.value));
                                                                                  }
                                                                              
                                                                                  function handleChangeB(event) {
                                                                                      setB(toNumber(event.target.value));
                                                                                  }
                                                                              ...
                                                                              

                                                                              То есть писать еще больше кода, который Svelte пишет за нас. И кстати, почему-то lodash тоже undefined к нулю не приводит, с чего бы это?
                                                                                0
                                                                                если бы был какой-то идеоматический способ конвертировать undefined в number

                                                                                Правильный вопрос: с какого фига там вообще взялся undefined?

                                                                                  0
                                                                                  То есть по-вашему лучше бы была пустая строка?)))
                                                                                    0

                                                                                    Лучше NaN. Либо число, либо не число. Ну или ошибка.

                                                                                      0
                                                                                      То есть вы считаете что в JS «отсутствует значение» — это NaN? А мне вот кажется, что это называется undefined. Но даже если уйти от религиозных споров, что правильнее и все такое, есть же чисто прикладной аспект — проверять на undefined значительно проще и удобнее, а значит:

                                                                                      <p>{a || 0}</p>
                                                                                      <p>{b || 0}</p>
                                                                                      
                                                                                      <script>
                                                                                        $: sum = (a || 0) + (b || 0);
                                                                                      </script>
                                                                                      

                                                                                      vs

                                                                                      <p>{isNaN(a) ? 0 : a}</p>
                                                                                      <p>{isNaN(b) ? 0 : b}</p>
                                                                                      
                                                                                      <script>
                                                                                        $: sum = (isNaN(a) ? 0 : a) + (isNaN(b) ? 0 : b);
                                                                                      </script>
                                                                                      

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

                                                                                        Я вам по секрету скажу: NaN — тоже ложно значение в условиях.

                                                                                          0
                                                                                          Подловили, сплоховал с примером)) Но не во всех стравнениях кстати. В любом случае, моя позиция простая по этому поводу:

                                                                                          1) Если переменная не содержит значения, то это не NaN, а undefined
                                                                                          2) С NaN в любом случае больше проблем чем с undefined

                                                                                          В итоге, если выбирать между приведением пустой строки к NaN или 0, я бы лучше выбрал 0, то не NaN. Уверен undefined тоже неспроста используют в Svelte.
                                                                                          –1
                                                                                          То есть вы считаете что в JS «отсутствует значение» — это NaN?

                                                                                          NaN — это не отсутствие значения, NaN — это Not a Number. '' — определенно Not a Number.


                                                                                          А мне вот кажется, что это называется undefined.

                                                                                          Ну вы еще заставьте пользователя таблицу приведения типов из js выучить.


                                                                                          есть же чисто прикладной аспект — проверять на undefined значительно проще и удобнее

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


                                                                                          В итоге, если выбирать между приведением пустой строки к NaN или 0

                                                                                          Если ваша ф-я приводит строку к числу, то результат работы такой ф-и не может быть undefined. Это шизофрения. Пустая строка — это не 0 и не undefined, это определенно NaN. Так же как и строка вида 'gfgfdgdf'. Кейс со строкой '' ничем не отличается от кейса со строкой 'gdfgdfgdf'.

                                                                                            0
                                                                                            NaN — это не отсутствие значения, NaN — это Not a Number. '' — определенно Not a Number.

                                                                                            Но когда юзер полностью отчищает поле для ввода, это не Not a Number, это отсутствие значение.

                                                                                            Ну вы еще заставьте пользователя таблицу приведения типов из js выучить.

                                                                                            Причем тут юзер? Это задача разработчика запроцессить данный кейс и с undefined это будет сделать проще, чем с NaN.

                                                                                            Это программисту проще и удобнее. А что проще программисту — не важно, это никого не волнует. Пользователь явно не хочет разбираться, что такое undefined и чем оно отличается от null.

                                                                                            Проще и очевиднее программисту, значит меньше ошибок и больше крайних случаев, таких как отчищение поля, который он может валидно запроцессить. А значит юзеру как раз и не надо будет думать про типы. Почему-то когда какой-то очередно JS связанный с числами, ломается в интернетах, я лично как юзер чаще вижу на экране непонятный NaN, чем undefined. Возможно потому, что одни разрабы думают как вы, тот работать с NaN не умеют, а другие разрабы думают как я, и вполне себе успешно хендлят undefined.
                                                                                              0
                                                                                              Но когда юзер полностью отчищает поле для ввода, это не Not a Number, это отсутствие значение.

                                                                                              Нет, значение не отсутствует. Это пустая строка.


                                                                                              Причем тут юзер? Это задача разработчика запроцессить данный кейс и с undefined это будет сделать проще, чем с NaN.

                                                                                              Чем проще? И выводите свой undefined вы именно юзеру. У вас там undefined + 5 = NaN.


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

                                                                                              Наоборот — крайних случаев меньше, либо у вас корректное число, либо NaN. Всего два случая. Вы же зачем-то при парсинге предлагаете добавить третий кейс — undefined. Какой в нем смысл, чем '' отличается в этом случае от 'gfdgfd' и зачем вообще нужны такие усложнения — не ясно.

                                                                                                0
                                                                                                Нет, значение не отсутствует. Это пустая строка.

                                                                                                Пустая строка для поля ввода числа?))) Нет уж, для меня, как для разработчика, понятнее undefined, чем пустая строка при вводе чила.

                                                                                                Чем проще? И выводите свой undefined вы именно юзеру. У вас там undefined + 5 = NaN.

                                                                                                Проще чем, что разоаботчику работать с undefined проще чем с NaN, а значит вероястность того, что вы вообще это увидите ниже. В случае с NaN ничем не лучше вообще, ибо NaN + 5 будет все тот же NaN. И в чем профит?

                                                                                                Наоборот — крайних случаев меньше, либо у вас корректное число, либо NaN. Всего два случая.

                                                                                                Да, у меня либо корректное число, либо нет значения, то есть undefined. NaN — это значение, но значение которое мне не нужно, то есть не валидное значение и с ним работать никак не могу. undefined — это отсутствие значения, такое бывает. В js мы всегда предполагаем, что переменная либо не имеет значения, то есть undefined, либо имеет валидное значение, в данном случае number. Вы же предлагаете добавить кейс с обработкой еще и невалидного значения.

                                                                                                Ок, рассмотрим пример, безотносительно Svelte:

                                                                                                let number; // undefined
                                                                                                
                                                                                                function setNumber(n) {
                                                                                                  number = n;
                                                                                                }
                                                                                                
                                                                                                setNumber(1); // 1 - valid
                                                                                                setNumber();  // undefined
                                                                                                setNumber(NaN);  // NaN - invalid
                                                                                                


                                                                                                Какой из кейсов лишний? По мне так очевидно, потому что на undefined мы в любом случае должны закладывать обработку, а вот еще и на NaN — это лишняя работа.
                                                                                                  –1
                                                                                                  Пустая строка для поля ввода числа?

                                                                                                  Да, пустая строка, значение ''.


                                                                                                  Проще чем, что разоаботчику работать с undefined проще чем с NaN,

                                                                                                  Чем проще?


                                                                                                  бо NaN + 5 будет все тот же NaN. И в чем профит?

                                                                                                  а undefined + 5 будет NaN. Проще тем, что сущностей две а не три. Зачем лишняя?


                                                                                                  Да, у меня либо корректное число, либо нет значения, то есть undefined.

                                                                                                  Так у вас есть значение. У вас есть строка '', вы ее парсите и числа не получается. Точно так же вы парсите, например, 'gfgdf' и у вас тоже числа не получается. В чем разница между этими двумя кейзами? Почему при ошибке парсинга одной строки — NaN, а при ошибке парсинга второй — undefined? Почему по сути эквивалентные кейзы у вас ведут себя по-разному? Обратите внимание, что, например, parseInt именно так и работает — либо NaN либо нормальное число. И никаких undefined или наллов или еще чего.


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

                                                                                                  Так невалидное значение в вашем случае это NaN. А отсутствия значения быть не может, оно всегда есть.


                                                                                                  Какой из кейсов лишний? По мне так очевидно, потому что на undefined мы в любом случае должны закладывать обработку

                                                                                                  Не должны, т.к. undefined быть в строке не может, этот кейс лишний. В строке всегда строка. Если она пустая — это будет ''. Не undefined.
                                                                                                  А вот NaN у вас в любом случае будет, если вы попытаетесь распарсить 'gfgdf'. По-этому NaN исключить нельзя.

                                                                                                    0
                                                                                                    Да, пустая строка, значение ''.

                                                                                                    Для меня это звучит скорее как баг в элементе input type=number.))

                                                                                                    Чем проще?

                                                                                                    Нет кейсов когда нужно использовать isNaN, проще сравнить 2 undefined чем 2 NaN. И все другие геморы связанные с NaN.

                                                                                                    а undefined + 5 будет NaN. Проще тем, что сущностей две а не три. Зачем лишняя?

                                                                                                    Мне кажется или в ответ на мой ответ на ваш ответ, вы написали тот же ответ? Чтож продолжу эту славную традицию:

                                                                                                    let number; // undefined
                                                                                                    
                                                                                                    function setNumber(n) {
                                                                                                      number = n;
                                                                                                    }
                                                                                                    
                                                                                                    setNumber(1); // 1 - valid
                                                                                                    setNumber();  // undefined
                                                                                                    setNumber(NaN);  // NaN - invalid <- это 3-й кейс
                                                                                                    


                                                                                                    Так у вас есть значение. У вас есть строка '', вы ее парсите и числа не получается. Точно так же вы парсите, например, 'gfgdf' и у вас тоже числа не получается. В чем разница между этими двумя кейзами?

                                                                                                    Никакой, оба их них дадут мне undefined в биндиге Svelte? Это же не number.

                                                                                                    Почему при ошибке парсинга одной строки — NaN, а при ошибке парсинга второй — undefined? Почему по сути эквивалентные кейзы у вас ведут себя по-разному?

                                                                                                    А с чего вы это взяли?

                                                                                                    Обратите внимание, что, например, parseInt именно так и работает — либо NaN либо нормальное число. И никаких undefined или наллов или еще чего.

                                                                                                    Если бы web api были удобной и продуманной штукой, мы бы с вами не сидели так плотно на фреймворках, либах и других lodash'ах.

                                                                                                    Так невалидное значение в вашем случае это NaN. А отсутствия значения быть не может, оно всегда есть.

                                                                                                    Так если стерли все = значения нет же. А вы говорите всегда. Мне кажется нормальным просто не давать ввести в поле для ввода числа текст. Например, когда я на сайте ввижу поле для ввода телефона, и мне не дают туда ввести `hello world`, меня это почему-то ни разу не смущало.

                                                                                                    Не должны, т.к. undefined быть в строке не может, этот кейс лишний. В строке всегда строка. Если она пустая — это будет ''. Не undefined.

                                                                                                    Биндинг пытается сделать из якобы input type=number, который при этом свободно принимает строки, настоящий number, который строки вообще не принимает. Тем самым юзер сразу понимает, что вводит чухню. undeined — это кейс от которого никак не избавиться, потому что js так работает и у нас переменная, у нас аргументы функций и все такое. А вот дополнительно вводить NaN в эту задачу смысла нет. Выше я привел все примеры. Захотите — изучите.

                                                                                                    А вот NaN у вас в любом случае будет, если вы попытаетесь распарсить 'gfgdf'. По-этому NaN исключить нельзя.

                                                                                                    Вы бы сперва хоть проверили как это работает, прежде чем писать то: svelte.dev/repl/2b7f5eeb4eea44978693b0c3c421b8bd?version=3.3.0

                                                                                                    Вот попробуйте туда ввести 'gfgdf'. Удачи!
                                                                                                      +1
                                                                                                      Для меня это звучит скорее как баг в элементе input type=number.))

                                                                                                      Баш — это когда что-то работает с нарушением спецификации. Инпут работает в согласии со спецификацией.


                                                                                                      Мне кажется или в ответ на мой ответ на ваш ответ, вы написали тот же ответ?

                                                                                                      Вы не можете несколько строк прочитать? Еще раз — у вас гарантированно есть NaN, т.к. undefined + 5 = NaN. Вы не можете от него отказаться, т.к. он по факту у вас есть, вы вынуждены его обрабатывать. С-но выбор между NaN + 5 = NaN и undefined + 5 = NaN. В первом случае две сущности, во втором — три. Что вам тут непонятно?


                                                                                                      Так если стерли все = значения нет же.

                                                                                                      Как нет, если оно есть. Это пустая строка. Напишите в консоли undefined === '', вам вернет false. undefined (отсутствие значения) и '' (пустая строка) — это разные вещи. Что вам непонятно-то тут?


                                                                                                      Например, когда я на сайте ввижу поле для ввода телефона

                                                                                                      Не дать ввести что-либо кроме телефона легко, а вот не дать ввести что-либо кроме чисел — очень нетривиальная задача. Вы просто явно с такими задачами не встречались.


                                                                                                      это кейс от которого никак не избавиться, потому что js так работает

                                                                                                      js как раз так не работает. В форме у вас пустая строка — не undefined. Когда вы эту строку засовываете в parseInt(), то получается NaN (и никогда не получается undefined). Если засунуть эту строку в Number — получится 0 (или NaN в случае 'gdfgdf' — но, снова, никаких undefined).
                                                                                                      Никогда и ни при каких обстоятельствах в js в данном контексте не бывает undefined.


                                                                                                      Никакой, оба их них дадут мне undefined в биндиге Svelte?

                                                                                                      То есть вы вообще в своих биндингах сломали js-ную логику парсинга чисел.

                                                                                                        0
                                                                                                        Баш — это когда что-то работает с нарушением спецификации. Инпут работает в согласии со спецификацией.

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

                                                                                                        Вы не можете несколько строк прочитать? Еще раз — у вас гарантированно есть NaN, т.к. undefined + 5 = NaN. Вы не можете от него отказаться, т.к. он по факту у вас есть, вы вынуждены его обрабатывать. С-но выбор между NaN + 5 = NaN и undefined + 5 = NaN. В первом случае две сущности, во втором — три. Что вам тут непонятно?

                                                                                                        Это вам тут не понятно, у меня есть 2 переменные, которые я могу чекать и еще как-то процессить и есть выражение, к которому вы аппелируете. Напомню как вам код:

                                                                                                        <!-- undefined + 5 = NaN -->
                                                                                                        {a} + {b} = {a + b}
                                                                                                        

                                                                                                        Так вот ваш NaN, от которого я яковы не могу отказаться, это результат выражения, а не переменной. Его нет в стейте напрямую и ни одна из переменных не может принять это значение в том случае о котором пишу я. Это результат inline операции над необработанными значениями переменных. Если я их обработаю должным образом, данная операция НИКОГДА не примет значение NaN, то есть он будет исключен из уравнения. А вот undefined вы исключить никак не можете, потому что просто создавая переменную без начального значения или вызваете функцию без аргумента, сразу получаете undefined в списке возможных значений. Так работает JS, увы. И раз NaN я могу исключить, кроме того я ним тяжелее работать, а undefined я исключить не могу никак. Уж лучше я буду работать с двумя вариантами: валидное значение (число) и отсутствие значения (undefined).

                                                                                                        Как нет, если оно есть. Это пустая строка. Напишите в консоли undefined === '', вам вернет false. undefined (отсутствие значения) и '' (пустая строка) — это разные вещи. Что вам непонятно-то тут?

                                                                                                        Пустая строка это не значение для типа number. Его нужно к чему-то привести. Вариантов 2, либо к 0, но почему? Либо принять что в качестве числа, пустая строка это отсутствие значения. Мне импонирует второе.

                                                                                                        Не дать ввести что-либо кроме телефона легко, а вот не дать ввести что-либо кроме чисел — очень нетривиальная задача. Вы просто явно с такими задачами не встречались.

                                                                                                        Тут просто задача напрямую так не ставится. Код приведение значения я приводил выше. Он крайне просто и логичен. Не знаю о чем вы тут спорите.

                                                                                                        js как раз так не работает. В форме у вас пустая строка — не undefined. Когда вы эту строку засовываете в parseInt(), то получается NaN (и никогда не получается undefined). Если засунуть эту строку в Number — получится 0 (или NaN в случае 'gdfgdf' — но, снова, никаких undefined).
                                                                                                        Никогда и ни при каких обстоятельствах в js в данном контексте не бывает undefined.

                                                                                                        Я писал о другом. undefined — всегда есть в списке вероятных значений для переменной или аргументы функции. От него никак не избавиться.

                                                                                                        То есть вы вообще в своих биндингах сломали js-ную логику парсинга чисел.

                                                                                                        Точно! Взяли и придумали удобную)
                                                                                                          0
                                                                                                          К сожалению, веб спеки не отличаются продуманностью.

                                                                                                          А к багам это какое отношение имеет?


                                                                                                          Это вам тут не понятно, у меня есть 2 переменные, которые я могу чекать и еще как-то процессить и есть выражение, к которому вы аппелируете.

                                                                                                          Вы опять не прочитали, что я пишу. Еще раз, у вас уже есть NaN. Потому что undefined + 5 = NaN. С-но вы не выбираете "число + NaN" вс "число + undefined", вы выбираете "число + NaN" вс "число + NaN + undefined". И вы почему-то топите за первый вариант. Почему? Я это пытаюсь у вас выяснить.


                                                                                                          Так вот ваш NaN, от которого я яковы не могу отказаться, это результат выражения, а не переменной.

                                                                                                          И это не отменяет того факта, что вы должны его обработать.


                                                                                                          Если я их обработаю должным образом, данная операция НИКОГДА не примет значение NaN

                                                                                                          Как не примет, если у вас она по факту в вашем примере NaN принимает. Кроме NaN еще, кстати, надо infinity обрабатывать.


                                                                                                          А вот undefined вы исключить никак не можете

                                                                                                          undefined я могу исключить просто потому, что в js из inputa этот undefined никогда не придет.


                                                                                                          И раз NaN я могу исключить

                                                                                                          Не можете, не сломав инпут.


                                                                                                          Пустая строка это не значение для типа number. Его нужно к чему-то привести.

                                                                                                          Любая строка — не значение для типа number.Чтобы строка стала числом — ее надо распарсить. ВАjs, Если вы парсите строку, которая является корректным числом, вы получаете это число. Если вы парсите строку, которая не является корреткным числом — вы получаете NaN. но не при каких обстоятельствах вы не получаете при парсинге строки undefined.


                                                                                                          Тут просто задача напрямую так не ставится. Код приведение значения я приводил выше. Он крайне просто и логичен.

                                                                                                          А непустую некорректную строку вы к чему и как приводите? И почему алгоритм вашего приведения нарушает спеку js? Зачем?


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

                                                                                                          js — динамический язык, по-этому в списке вероятных значений для переменной или аргументов ф-и есть все вообще.
                                                                                                          Если, однако, мы говорим о инпуте — то мы знаем, что там будет всегда строка. Если мы говорим о результате парсинга этой строки — мы знаем, что там число или NaN. И еще мы знаем, что undefined там не бывает.

                                                                                        –2

                                                                                        Лучше бы было то, что ввёл пользователь, без потери информации.

                                                                                          0
                                                                                          Не согласен. Поле для ввода числа подразумевает ввод числа, также как поле для ввода телефона, поразумевает ввод телефона, а email ну вы поняли. Ограничить ввод символов в email сложно, там много чего может быть. А вот запретить ввод любых символов кроме числе в input type=number, вполне себе реально. Так и работает.
                                                                                            +1

                                                                                            Вводим "2e" — инпут очищается. Как пользователю ввести число "2e10"?
                                                                                            Вводим "2." — инпут очищается. Как пользователю ввести число "2.1"?
                                                                                            Вводим "e2" — текст остаётся в инпуте. Очень похоже на число, да.
                                                                                            Вводим "--1" — текст остаётся в инпуте. Очень похоже на число, да.

                                                                                              +1
                                                                                              Бонусные очки:
                                                                                              Вводим «e2», добавляем в начале 1 — мгновенно получаем 100.
                                                                                              Вводим «e100», добавляем в начале 0 — мгновенно получаем 0 (дробная часть — не, не слышали).
                                                                                              Вводим «e100», добавляем в начале 1 — о, ура, получили «1e+100»!
                                                                                              Вводим ".e10", добавляем 1 после точки — получаем 1000000000. Дробная часть из нескольких цифр? Не, не слышали.
                                                                              +1

                                                                              Забавно, как у нас с вами разнятся ожидания. Хотя это вопрос стандартизации.
                                                                              Вот от date я бы на 97% ожидал именно тип даты. А вот с номером телефона и в каком формате если строка — тут вопрос. Скорее это таки long без форматирования, который можно представлять в любом формате в строке. Или массив цифр, чтоб ни у кого не было соблазна оперировать номером телефона как числом.

                                                                                –1
                                                                                Вот от date я бы на 97% ожидал именно тип даты.

                                                                                Здесь возникает вопрос с часовыми поясами. new Date('2019-05-12') вернет вам полночь в вашей таймзоне, а в других поясах это будет другое число.

                                                                                  +1

                                                                                  Хранить всегда в UTC? Или, по крайней мере, записывать. А при чтении из date вы сможете получить как локализованное значение, так и UTC, так и с любым другим сдвигом.

                                                                                    +1

                                                                                    Получится какой-то такой код


                                                                                    const value = '2019-05-12';
                                                                                    // Date.UTC принимает только числа, поэтому парсим строку руками
                                                                                    const [year, month, day] = date.split('-'); 
                                                                                    const date = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));
                                                                                    console.log(date.getUTCDate()); // будет всегда 12 в любой таймзоне, как нам и хотелось

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


                                                                                    Как мне кажется, это хорошо что и нативный input, и svelte для дат возвращают ее строковое представление, чтобы разработчик сам его обрабатывал как надо.

                                                                            0
                                                                            Не до конца понял, что вы имеете ввиду под «рантайм» о котором надо помнить. В Svelte не нужно даже понимать как это работает, чтобы использовать. Наоборот компилятор пытается понимать что вы хотите написать, и дописывает за вас утилитарные вещи. Поэтому рантайма как раз тут нет о котором надо думать. Более того, в отличии от реакт, где огромные рантайм абстракции зашиты внутрь фреймворка, на Svelte вы можете за минуту прочитать весь код вашего компонента на любом этапе его написания и совершенно точно знать как он работает. Потому что это максимально прямолинейный, низкоуровневый, заточенный под задачу (текущий код компонента) императивный код. Попробуйте REPL, попишите код, загляните во вкладку JS Output. Если вы не сможете понять как это работает за 5 минут, я куплю вам пиво.

                                                                            И еще пример из реакт:

                                                                            this.setState({ foo: 1 }); // {foo} НЕ используется в шаблоне JSX
                                                                            


                                                                            Вам ведь надо «помнить» что вызов setState() вызовет rerender + reconcile даже если {foo} не используется в шаблоне вообще!!!??? В Svelte вы полностью избавлены от таких проблем)

                                                                              0
                                                                              В Svelte вы полностью избавлены от таких проблем)

                                                                              Наоборот же — в svelte надо помнить, что если foo в шаблоне нет, то рендер не будет вызван :)


                                                                              Логика реакта с безусловным рендером в этом плане явно проще.

                                                                                +1
                                                                                Наоборот же — в svelte надо помнить, что если foo в шаблоне нет, то рендер не будет вызван :)

                                                                                Извините, а зачем нам рендер, если foo нет связан с DOM? Или в этом просто какой-то сокральный смысл есть?

                                                                                Логика реакта с безусловным рендером в этом плане явно проще.

                                                                                Она не проще, а просто тупее. Нам же памяти не жалко, пусть гоняет туда-сюда vdom, даже если это не имеет смысла.
                                                                                  –1
                                                                                  Извините, а зачем нам рендер, если foo нет связан с DOM?

                                                                                  А откуда я знаю, что он не связан? О том же и речь — в svelte мне надо помнить, что с чем связано.


                                                                                  Она не проще, а просто тупее.

                                                                                  KISS :)


                                                                                  Нам же памяти не жалко, пусть гоняет туда-сюда vdom, даже если это не имеет смысла.

                                                                                  Ну вообще-то да.

                                                                                    +1
                                                                                    А откуда я знаю, что он не связан? О том же и речь — в svelte мне надо помнить, что с чем связано.

                                                                                    Простите, но у вас задача-то какая? Вызвать рендер или показать значение?

                                                                                      0
                                                                                      А откуда я знаю, что он не связан? О том же и речь — в svelte мне надо помнить, что с чем связано.

                                                                                      Вопрос же в том, зачем вам об этом вообще думаю? Лично мне достаточно знать 2 вещи:

                                                                                      1) я хочу чтобы мой стейт всегда был синхронизирован в DOM
                                                                                      2) я знаю что Svelte делает это максимально эффективно.

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

                                                                                      KISS :)

                                                                                      В данном случае это Keep It So Stupid

                                                                                      Ну вообще-то да.

                                                                                      Именно поэтому реакт не подходит для многих проектов, особено для low-power устройств. И речь даже не о экзотических штуках, типа POS терминалах, на которых Svelte показал себя прекрасно, но я просто на мобильных и ТВ. Мы его лично пробовали на ТВ, это марк же.
                                                                                        –4
                                                                                        Если же не связана, то очевидно, я не хочу никаким образом нагружать свое приложение лишними вычислениями.

                                                                                        Так не факт, что они лишние.


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

                                                                                        Вопрос, зачем вообще использовать spa для low-power устройств, остается открытым.

                                                                                          +1
                                                                                          Так не факт, что они лишние.

                                                                                          Если foo не связан в DOM, то rerender + reconcile при его изменении — это безусловно лишние операции.

                                                                                          Вопрос, зачем вообще использовать spa для low-power устройств, остается открытым.

                                                                                          А React подходит только для SPA? Еще говорят Svelte имеет какие-то ограничения по области использования ;-) К вашему сведению, все приложения для TV это как правило SPA, потому что далеко не все платформы поддерживают запуск приложения с удаленного сервера, обычно файлы крутятся на локальном или даже по протоколу file://.

                                                                                            –2
                                                                                            Если foo не связан в DOM, то rerender + reconcile при его изменении — это безусловно лишние операции.

                                                                                            А вдруг рендер где-то что-то поменяет и в итоге изменятся данные, которые выводятся?


                                                                                            А React подходит только для SPA? Еще говорят Svelte имеет какие-то ограничения по области использования ;-)

                                                                                            Что реакт, что свелте, что все остальное — это спа-фрейморвки. Если вам не нужно спа, то у них нет преимуществ никаких по сравнению с vanillajs.


                                                                                            обычно файлы крутятся на локальном

                                                                                            Ну так и крутите на локальном, spa зачем? Можно спокойно написать логику на беке. Да и вообще было бы интересно увидеть конкретный кейс, где реакт тормозил, а вот свелте решил проблему. Ну и еще желательно пример какого-нибудь приложения на свелте хотя бы среднего (100kloc+) размера приложения, чтобы понимать, как это скалируется все.

                                                                                              0
                                                                                              А вдруг рендер где-то что-то поменяет и в итоге изменятся данные, которые выводятся?

                                                                                              Такого быть не должно.


                                                                                              Что реакт, что свелте, что все остальное — это спа-фрейморвки. Если вам не нужно спа, то у них нет преимуществ никаких по сравнению с vanillajs.

                                                                                              Обоснуйте. Не вижу никакой проблемы во вставке компонента реакт или свелте на любую страницу (кроме веса реакта).

                                                                                                –1
                                                                                                Такого быть не должно.

                                                                                                Не должно.


                                                                                                Не вижу никакой проблемы во вставке компонента реакт или свелте на любую страницу (кроме веса реакта).

                                                                                                Я тоже не вижу. Не вполне ясно, как это противоречит моим словам.

                                                                                                0
                                                                                                А вдруг рендер где-то что-то поменяет и в итоге изменятся данные, которые выводятся?

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

                                                                                                Говорите рендер что-то где-то поменяет? Хм, попробую себе представить:

                                                                                                <p>{bar()}</p>
                                                                                                <input bind:value={foo} type="number">
                                                                                                
                                                                                                <script>
                                                                                                  let foo = 0;
                                                                                                
                                                                                                  function bar() {
                                                                                                     return foo + 1;
                                                                                                  }
                                                                                                </script>
                                                                                                

                                                                                                Так что ли? Только в Svelte такие вещи делаются не так))) Можно через чистую функцию (если нравятся функции), а можно через вычисляемое выражение:

                                                                                                <p>{bar(foo)}</p>
                                                                                                <p>{baz}</p>
                                                                                                <input bind:value={foo} type="number">
                                                                                                
                                                                                                <script>
                                                                                                  let foo = 0;
                                                                                                
                                                                                                  function bar(foo) {
                                                                                                     return foo + 1;
                                                                                                  }
                                                                                                
                                                                                                  $: baz = foo + 1;
                                                                                                </script>
                                                                                                

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

                                                                                                Что реакт, что свелте, что все остальное — это спа-фрейморвки. Если вам не нужно спа, то у них нет преимуществ никаких по сравнению с vanillajs.

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

                                                                                                Ну так и крутите на локальном, spa зачем? Можно спокойно написать логику на беке.

                                                                                                А кто сказал что есть доступ к локальному серверу? Там же просто раздача статики. Что вы ерунду то пишете, не в курсе, так просто промолчали бы.

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

                                                                                                В видео к предыдущей статье был кейс с POS терминалами. Реакт тоже тестировался.
                                                                                                Ну и еще желательно пример какого-нибудь приложения на свелте хотя бы среднего (100kloc+) размера приложения, чтобы понимать, как это скалируется все.

                                                                                                А есть такие приложения в open-source для реакта? Пришлите ссылку, гляну, может напишу аналог. Правда придется при этом по фунционалу раздуть процентов на 50%. Ну чтобы сравняться по кол-ву строк кода с приложение на реакт.

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

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


                                                                                                  Если серьезно, по всей ветке — в линтере есть правило, которое дает ворнинг по неиспользуемым в шаблонах переменные стейта :)

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

                                                                                                    Удивили, признаюсь)) Тогда вообще не ясно чего вы так за него топите и что по-вашему «хорошо». Или вы эдакий вечно ворчливый дедька с клюшкой? Все вам не нравится, все говно.

                                                                                                    Если серьезно, по всей ветке — в линтере есть правило, которое дает ворнинг по неиспользуемым в шаблонах переменные стейта :)

                                                                                                    Во-первых, если для решения проблемы нужен линтер, то значит эта проблема есть. Во-вторых, линтер за вас не перепишет код, который уже завязан на foo и его setState. Хорошо бы, чтобы шаблон просто не ререндерился, если связанные с ним части стейта не поменялись. Я даже не понимаю с чем тут можно спорить. Ну хорошо ведь, а?
                                                                                                      0
                                                                                                      Тогда вообще не ясно чего вы так за него топите и что по-вашему «хорошо».

                                                                                                      Я не топлю, я просто сравниваю два разных подхода. Если вдруг что-то выглядит где-то как "топление" — ну ок, это просто так выглядит :)


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

                                                                                                      Да, это проблема из разряда "неиспользуемая переменная/ф-я". Ну, чтобы в коде мусора не было и не вспоминать через год, а что это там за yoba в стейте и не используется ли она как-то там где-то там :)


                                                                                                      Ну хорошо ведь, а?

                                                                                                      С точки зрения логики приложения без разницы.
                                                                                                      Пока мы не "ломаем" рендер (кейз с изменением чего-то там в рендере). Если ломаем (зачем-то, мало ли) — то рендерить всегда будет полезнее :)

                                                                                                        0
                                                                                                        Я не топлю, я просто сравниваю два разных подхода. Если вдруг что-то выглядит где-то как «топление» — ну ок, это просто так выглядит :)

                                                                                                        Да я понял, вы из Ангулярщиков. Кстати, ниче против ангуляра не имею, очень достойная вещь для энтерпрайзов. Наверное сам бы взял для очень крупного проекта. Благо очень крупными мы и не занимаемся, терпеть не могу такие проекты.

                                                                                                        Да, это проблема из разряда «неиспользуемая переменная/ф-я». Ну, чтобы в коде мусора не было и не вспоминать через год, а что это там за yoba в стейте и не используется ли она как-то там где-то там :)

                                                                                                        Не-не, это другое. Мы рассматриваем кейс, когда часть стейта перестала использоваться в шаблоне, а не вообще в компоненте. В том то и дело, что в компоненте на основе foo еще много чего может вычисляться и setState там тоже делается не просто так. А вот в шаблоне не используется(((

                                                                                                        С точки зрения логики приложения без разницы.
                                                                                                        Пока мы не «ломаем» рендер (кейз с изменением чего-то там в рендере). Если ломаем (зачем-то, мало ли) — то рендерить всегда будет полезнее :)

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

                                                                                                          –1
                                                                                                          Да я понял, вы из Ангулярщиков.

                                                                                                          Здесь, скорее, стоит речь вести о задачах. Я из тех, кто больше по тем задачам, для которых подходит ангуляр — так правильнее всего :)
                                                                                                          Если мне надо будет накидать гостевуху, я точно не буду писать ее на ангуляре. Может, возьму тот же свелте, из интереса просто :)
                                                                                                          Вы вот, как сами сказали, по другим задачам.


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

                                                                                                          Ну вот опять же это вопрос задачи. Приложение должно быть достаточно производительным. Просто если вы пишите под низкопроизводителные устройства, то у вас граница, где "достаточно" переходит в "п*здец как тормозит" проходит очень близко, с-но, вам всегда и приходится о производительности думать. Если же эта граница далеко — то, с-но, думать об этом смысла нет, пока она не приблизится :)

                                                                                                            0
                                                                                                            тем задачам, для которых подходит ангуляр

                                                                                                            О, я бы послушал про эти задачи.

                                                                                    0
                                                                                    Вам ведь надо «помнить» что вызов setState() вызовет rerender + reconcile даже если {foo} не используется в шаблоне вообще!!!???

                                                                                    А зачем нужно свойство, от которого не зависит визуализация?

                                                                                      0
                                                                                      Рудимент от прежнего кода, например, раньше использовалось в шаблоне, потом удалили из шаблона, но на него остались завязаны еще какие-то вычисления. Будем переписывать все места использования для каждой такой ситуации или просто будем использовать фреймворк, который не будет ререндерить все на каждый пчих?
                                                                                        +1
                                                                                        Будем переписывать все места использования для каждой такой ситуации
                                                                                        Я однозначно за «переписать». Негоже в коде мусор оставлять
                                                                                          +1
                                                                                          Главное не забыть/забить. ;-) Мне лично кажется, что лучше было, что если стейт, связанный с шаблоном не изменился, то и никаких ререндеров не происходит. Просто и понятно — извинили стейт, используется в шаблоне — rerender, не используется — ничего.
                                                                                      –1
                                                                                      Вот как раз это помнить не стоит сразу. Об этом нужно вспомнить, когда это станет проблемой. Оптимизацией нужно заниматься тогда, когда это нужно, как бы это не звучало)
                                                                                      Под рантаймом я как раз и подразумеваю неявные штуки, которые фреймворк/либа делает за меня. Вам про числа уже много написали, что ожидается порой совсем другое. А если вы все же настаиваете на своем, то почему у инпута типа date нет приведения к дате? Или есть?)

                                                                                      Более того, синтаксис — учи еще один язык. Чего стоят только вот такие штуки:
                                                                                      {#await promise then value}
                                                                                      	<p>The value is {value}</p>
                                                                                      {/await}
                                                                                      


                                                                                      В общем, без полбутылки не разберешься. Писать вот так сразу на нем куда сложнее, чем на vue или react. Там реально есть интуитивные штуки.
                                                                                        0
                                                                                        Вот как раз это помнить не стоит сразу. Об этом нужно вспомнить, когда это станет проблемой. Оптимизацией нужно заниматься тогда, когда это нужно, как бы это не звучало)

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

                                                                                        Под рантаймом я как раз и подразумеваю неявные штуки, которые фреймворк/либа делает за меня.

                                                                                        Любая абстракция в рантайме — это не явная штука которую фреймворк делат за вас. Вот вы уверены что совершенно точно знаете как ведет себя «машинка» реакта конкретно для вашего компонента? А для Svelte я знаю совершенно точно, потому что я могу просто открыть итоговый код компонента и прочитать его полностью за 1-2 минуты, ибо там нет вообще никакой подкапотной магии. Я могу БЕЗ ДЕБАГГЕРА совершенно точно сказать какая операция моего компонента какие именно действия будет производить, а вы в реакт так можете? Нет. Это то что я называю «рантаймом».

                                                                                        Вам про числа уже много написали, что ожидается порой совсем другое.

                                                                                        Ожидаете другое? Не юзайте встроенный 2way биндинг, юзайте такой же ивент хендлер как в реакт, получайте строку и делайте с ней что надо. Одно другому не мешает. Только в Svelte и том же Vue и Angular у нас такая возможность есть, а в реакт ее просто нет.

                                                                                        А если вы все же настаиваете на своем, то почему у инпута типа date нет приведения к дате? Или есть?)

                                                                                        А с какие пор у нас Дата — это примитивный тип? Поэтому и не приводится. Для Boolean кстати тоже приведение идет, например если это чекбокс:

                                                                                        <script>
                                                                                          let checked = true;
                                                                                        </script>
                                                                                        <input type="checkbox" bind:checked={checked}>
                                                                                        <p>{typeof checked}</p> <!-- boolean -->
                                                                                        


                                                                                        Более того, синтаксис — учи еще один язык.

                                                                                        Синтаксис любых DSL для HTML надо учить. Тот же Angular и Vue. Синтаксис HTMLx, который использует Svelte не сложнее чем у них уж точно. А ежели вы топите за JSX, то хочу вас расстроить, там тоже много чего надо учить, даже если вы знаете JS. А уж HTML лучше вообще не знать, а то использовать JSX будет болью.

                                                                                        Чего стоят только вот такие штуки:

                                                                                        Вы их и учить то не можете, потому что нигде таких штук больше нет. А {#await} кстати очуменно удобная штуковина.

                                                                                        В общем, без полбутылки не разберешься. Писать вот так сразу на нем куда сложнее, чем на vue или react. Там реально есть интуитивные штуки.

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

                                                                                        <>
                                                                                          <h1 style="color:red">Hello {name}!</h1>
                                                                                          <input value={name} onChange={e => setName(e.target.value)}>
                                                                                          <hr>
                                                                                        
                                                                                          {(() => {
                                                                                            if (count < 10) {
                                                                                              return <button onClick={e => setCount(count + 1)}>
                                                                                                Clicks {count}
                                                                                              </button>;
                                                                                            } else {
                                                                                              return <>
                                                                                                <p>Clicks limit overcome</p>
                                                                                                <button onClick={e => setCount(0)}>Drop</button>
                                                                                              </>;
                                                                                            }
                                                                                          })()}
                                                                                        </>
                                                                                        


                                                                                        <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}
                                                                                        


                                                                                        Все примеры идентичны и в любом из этих примеров есть что «поучить», несмотря на то, что мы даже до работы с массивами не добрались. Если вы конечно работаете с каким-то из этих DSL много лет, наверное вам он кажется более понятным, чем остальне. НО, только один из этих примеров не работает… Именно он, тот самый интуйтивный. ;-)
                                                                                    +2
                                                                                    Если следовать посылу заголовка, а именно, писать меньше кода, то надо ещё и Angular рассмотреть.
                                                                                    Пример на Angular
                                                                                    image

                                                                                    Количество именно написанного кода соизмеримо со Svelte — две переменные и три HTML-элемента. Остальное автоматически генерирует CLI и на эту обвязку при работе вообще не обращаешь внимания. При этом, за один раз ты смотришь либо код компонента, либо представление. Что ещё больше сокращает количество информации, которую надо охватить за раз.
                                                                                      +3

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

                                                                                        +2
                                                                                        Кривая обучения у Ангуляра гораздо круче, чем у Реакта или Вью. Слишком много непривычных новых концепций надо сразу освоить.
                                                                                          +1

                                                                                          Для бекендщиков ровно наоборот

                                                                                            0
                                                                                            А мы тут с детьми программированием занимаемся что ли? Взял и изучил.
                                                                                              +1
                                                                                              Зачем? Есть куча других фреймворков которые не требуют эти знания, но которые дают тоже самое но с болъшей скоростью, меньшим размером и т.д. Следовательно эти концепции ненужные и вредные
                                                                                                0
                                                                                                Есть куча других фреймворков которые не требуют эти знания, но которые дают тоже самое но с болъшей скоростью, меньшим размером и т.д.

                                                                                                Какие?
                                                                                                  0

                                                                                                  Тоже интересно узнать

                                                                                                    +2
                                                                                                    react, vue, svelte?
                                                                                                      0

                                                                                                      Не могу говорить за svelte, но в первых двух все не так, ничего они не дают, особенно реакт, особенно по скорости разработки

                                                                                                    +2
                                                                                                    Это пока занимаешься формошлёпством. Что-то более-менее крупное, с командой больше 3-4 человек и растянутое во времени на месяцы/года, и тут ангуляр с его кривой обучения, его фреймвёрком и его подходами не так уж плох.
                                                                                                    0

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

                                                                                                0
                                                                                                Осталось сравнить количество кода для реализации v-model/ngModel/bind:value/value+onChange на кастомном поле ввода для каждого из фреймворков.
                                                                                                  0
                                                                                                  Уточните пожалуйста что имеете ввиду?
                                                                                                    0
                                                                                                    Имелся в виду кастомный компонент ввода. DateRange какой-нибудь. Или автокомплит с серверным поиском.