Открыть список
Как стать автором
Обновить

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

ай, ладно… всё равно сейчас кто-то напишет это… Так почему не MobX?

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

Писец, ну как так то а?

2021 год на дворе и фронтенд разработчик пишущий на React'e не знает что такое MobX и не попробовал его в реальной жизни. Ясен перец если бы вы его попробовали в бою, то ни о каких Redux'ах тут бы даже речи не было и не вернулись бы вы к этому недоразумению никогда.

Может вы ещё не слышали что вместо callback hell и promise.then.then.then можно писать async/await или слышали, но не пробовали?

Может вы и Vue3 не пробовали по сей день и Svelte да?

Вот такие вот нынче на рынке «разработчики».
Но с другой стороны нам же проще, конкуренции нет в мире Senior'ов и Lead'ов, их категорически сложно найти.
Достаточно скоропалительный вывод вы делаете. Я пробовал, мне не понравилось :), но я не делаю из своих ощущений выводы на сколько хороша эта библиотека. Лично для меня она оказалась не удобной.
Я пробовал, мне не понравилось :)

А что конкретно вам не понравилось? Я хочу узнать ваше мнение.
Лично для меня она оказалась не удобной.

А что конкретно вам в MobX'e не удобно?
ivahaev На вопросы вы не ответите да? Очередные пустые слова? Я конечно понимаю что много кто их бросает на хабре, но всё же, вдруг вы исключение.
Начнем с того, что я высказал своё мнение, я его никому не навязываю.
Сейчас сложно вспомнить, что именно, так как времени прошло достаточно много. Плюс, для того, чтобы квалифицированно высказываться о чем-то, нужно некоторое время плотно с этим поработать. Моё знакомство было поверхностным. Я в мобиксе не увидел сходу чего-то, чего нельзя сделать на обычных кастомных рекатовски хуках, например. Не понравилась концепция разнозненных микро-стоейтов, которые потенциально могу привести к циклическим зависимостям. Ну и я там не увидел Flux :)
Сейчас сложно вспомнить, что именно, так как времени прошло достаточно много.

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

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

И в чем проблема поработать с этим? 1-2 вечеров хватить более чем достаточно чтобы раскрыть потенциал и понять как это работает. Вы же себя вроде как разработчиком называете, а сами кроме react + redux ничего не пробовали и не знаете. Обычно такие люди себя называют «React разработчик», т.е. супер узконаправленный кругозор и категорическое нежелание смотреть по сторонам, чтобы видеть что вообще происходит, какие есть технологии, как можно писать код намного лучше, чем пишете вы сейчас и т.п.

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

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

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

Нет никакой концепции, хотите единый стор — пожалуйста. Хотите микро стейты — пожалуйста. Вообще любой каприз, MobX вас ни в чем не ограничивает и ничего не диктует.

Ну и я там не увидел Flux :)

И что? С чего бы ему там взяться то вообще? Поэтому MobX такой и крутой, что там нету Flux. Там вообще про другое.
Ну да, конечно, стандартная отмазка) Это было давно, я ничего не помню бла-бла-бла.

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


Откуда их столько??

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

1) Просто молчать и игнорировать. (Что он и делал изначально, но потом похоже не сдержался и добавил сверху второй вариант)
2) Сказать — "просто это было очень давно, поэтому я ничего не помню и разумеется ни чего вам не ответу по существу. А так да, я пробовал мне не понравилось и другим не советую.".

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

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

Интересно, почему ваш коммент минусуют… Возможно, из-за async/await? С ними сложно работать, так как уходишь в try-catch hell для имплементации того функционала, который был бы однострочным с Promise. Также сам концепт псевдосинхронного кода, когда не понимаешь (либо легко пропустить при чтении), что последующий код будет выполнен не сейчас, а в неопределенном будущем. В концепте MobX видел, как в not strict mode люди забывали писать runInAction (да, конечно я знаю о schedule, который может это автоматизировать — но не видел в проектах), что приводило к лишним ререндерам. В целом я придерживаюсь Promise — это простой инструмент с явным потоком в рамках многим привычного middleware паттерна, но без глобалок. Не отрицаю, что можно и с асинками писать грамотный код и путем составления best practice минимизировать ошибки, но сама формализация best practice — редкость, так что лучше уж Promise.


Может, поэтому минусовали… А так-то здравые рассуждения, пусть и немного эмоционально)

Возможно, из-за async/await? С ними сложно работать, так как уходишь в try-catch hell для имплементации того функционала, который был бы однострочным с Promise

try-catch hell? Где он?) В выдуманном кейсе?)
    fetchData2 = async () => {
        this.isFetching = true;
        this.errorMessage = null;

        try {
            const response = await getApiDate();

            this.item = response;
            this.errorMessage = null;
        } catch (e) {
            console.error(e);
            this.errorMessage = e.message;
        } finally {
            this.isFetching = false;
        }
    };

    fetchData4 = async () => {
        this.isFetching = true;
        this.errorMessage = null;

        try {
            const items = await getApiDate();
            const itemIds = items.map(item => item.id);
            const dataDependsOnItemIds = await getApiDate2(itemIds);
            
            const transfomeddata = {}; // lala
            
            this.data = transfomeddata;
            this.errorMessage = null;
        } catch (e) {
            console.error(e);
            this.errorMessage = e.message;
        } finally {
            this.isFetching = false;
        }
    };

Где однострочная имплементация?
    fetchData3 = async () => {
        this.isFetching = true;
        this.errorMessage = null;

        getApiDate()
            .then((response) => {
                this.item = response;
                this.errorMessage = null;
            })
            .catch((e) => {
                console.error(e);
                this.errorMessage = e.message;
            })
            .finally(() => {
                this.isFetching = false;
            });
    };

    fetchData5 = async () => {
        this.isFetching = true;
        this.errorMessage = null;

        getApiDate()
            .then((items) => {
                const itemIds = items.map(item => item.id);
                return getApiDate2(itemIds);
            })
            .then((dataDependsOnItemIds) => {
                const transfomeddata = {}; // lala

                this.data = transfomeddata;
                this.errorMessage = null;
            })
            .catch((e) => {
                console.error(e);
                this.errorMessage = e.message;
            })
            .finally(() => {
                this.isFetching = false;
            });
    };


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

async/await есть давным в разных языках, в JS он пришел поздно. И то, в 2016 его уже можно было использовать, то есть как бы 5 лет уже.
Что тут может быть непонятного или что можно пропустить я не понимаю, по-моему всё очевидно и элементарно. И работает всё ровно так, как ты ожидаешь. А вот цепочку из промисов читать сложнее, чем код написанный в синхронном стиле, а учитывая то, что цепочка промисов это цепочка callback'ов, то тут вы сами понимаете чем это пахнет да?)

В концепте MobX видел, как в not strict mode люди забывали писать runInAction (да, конечно я знаю о schedule, который может это автоматизировать — но не видел в проектах), что приводило к лишним ререндерам.

Да это на самом деле всё ерунда и баловство, 1-2 лишних рендера вообще погоду не сделают, а вот чистый и приятно читаемый код ещё как сделает, в отличии от грязного, завернутого в runInAction, action, ради псевдо чувства, что таким образом твое приложение будет работать быстрее, хотя по факту это не так, оно быстрее от этого не станет. Я уже давно отказался от этой ерунды и все текущие приложениях в которых были action/runInAction работают с точно такой-же скоростью, когда я их полностью убрал, вот прям 1 в 1, извините 1-2 микросекунды разны я в расчет не беру, это не бэкенд, где это играет роль при большом RPS.
Я уже давно отказался от этой ерунды и все текущие приложениях в которых были action/runInAction работают с точно такой-же скоростью, когда я их полностью убрал, вот прям 1 в 1, извините 1-2 микросекунды разны я в расчет не беру

А на каком железе вы это тестили? Пробовали на каком-нибудь low-end, типа ноутов с селеронами N3050 или мобилках стоимостью до 10 т.р.?

А на каком железе вы это тестили? Пробовали на каком-нибудь low-end, типа ноутов с селеронами N3050 или мобилках стоимостью до 10 т.р.?

Нет не тестил, я такими устройствами не пользуюсь, да и нету их в наличии, но опять же 1-2 лишних рендера не сделают погоды даже на таких устройствах, если вы не рендерите списки длинною в тысячи элементов конечно. Плюс целевая аудитория проектов на которых я работаю точно не пользуется такими девайсами.
А так, если для вас цель номер один это максимальная производительность в браузере, то React не про это, вам тогда надо смотреть в сторону голого JS'a или Svelte, а ещё лучше по старинке с минимумом JS'a где какой ни будь PHP генерирует готовый HTML и выплевывает его.
Лично я минусовал за то, что не нужно в том же 2021 году публично оценивать разработчика на основе того, что он пробовал, а что нет.

Если бы оценивали только по принципу «а что пробовал в реальной жизни», то конкуренция среди Senior'ов и Lead'ов уж точно бы давно зашкаливала;)
Простите, но статью нужно назвать «как потратить три на то, что делается за 5 минут»:)
Сейчас в моде херак-херак и в продакшн!
Спасибо за содержательный комментарий :). Если вас не заботит качество создаваемого продукта, тогда ваш «модный» подход подойдёт гораздо лучше. А когда вас интересует простота развития и поддержки продукта, снижение количества багов, то добро пожаловать в волшебный мир TDD
Замечу, что с развитием навыка написания тестов, скорость разработки не только не снижается, а даже ещё и повышается.
Да нет, у меня претензии к редуксу, а не к жесту. Ваша статья — хороший пример количества бойлерплейта, необходимого на каждый чих. Оно ведь не просто про «много писать», оно ещё про «много выполнять».
Всё так, именно поэтому заготовлено продолжение про Redux Toolkit, где всё на много проще и красивее становится.

"Для того, чтоб сделать хорошо — достаточно лишь сначала сделать плохо, а потом вернуть всё как было" (с)

Это очень хорошее правило и даже рабочее, только здесь немного иная ситуация. Очень полезно понимать концепцию работы библиотеки, для того, чтобы использовать её по-полной. Таким образом, зная, как это работает изнутри, можно смело брать инструменты, которые упрощают жизнь разработчика. От обратного идти несколько сложнее.
Спасибо за реальный пример. Странно, что вы не использовали React testing library. Значительно облегчает написание тестов для компонентов, которые используют контекст.

Я сделал Create react app template с примером простого Redux приложения и необходимыми тестами — github.com/morewings/cra-template-quickstart-redux
Спасибо за пример альтернативного подхода.
React testing library рендерит DOM, что несколько более накладно, чем получение JSON представления дерева. react-test-renderer закрывает все наши потребности, это удобная и достаточно быстрая библиотека.
На самом деле, просто попробовали обе, выбрали ту, которая лучше подошла под наши задачи. Дополнительно обмазали это всё дело кастомными матчерами для жести, стало совсем приятно.
Видно, что тесты у вас аккуратные. Но во многих местах вы тестируете код, а не поведение и функциональность.
Приведите пример?
Как и обещал, привожу пример.

Вот здесь, например, вы тестируете action creator

import { checkboxClick } from '.'

describe('checkboxClick', () => {
  it('returns checkboxClick action with action name in payload', () => {
    const checkboxName = 'anyCheckbox'

    const result = checkboxClick(checkboxName)

    expect(result).toEqual({ type: 'checkbox/click', payload: checkboxName })
  })
})


Теперь я, другой разработчик, попробую прочитать этот тест и понять, что же вы тестируете? Я вижу, что вы проверяете возвращаемое функции на предмет соответствия заданному матчеру. То есть функция должна возвращать объект со свойствами `type` и `payload`. Что я вам скажу, как другой разработчик на этом проекте? Спасибо, кэп.

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

Вот как я тестирую action creators

/** Note that tests functions are async */
    it(`it handles successful API query`, async () => {
      const {result} = renderHook(() => useActions(), {
        wrapper: ({children}) => <Provider store={store}>{children}</Provider>,
      });

      /** Mock response from API */
      const response = 6;

      mockAxios.onGet(config.randomAPI).reply(200, response);

      /**
       * Wait until async action finishes
       */
      await result.current.getNumber();

      /** First dispatched action should have _PENDING suffix */
      expect(store.getActions()[0]).toEqual({
        type: `${GET_RANDOM_NUMBER}_PENDING`,
      });

      /** Second dispatched action should have _FULFILLED suffix */
      expect(store.getActions()[1].type).toEqual(
        `${GET_RANDOM_NUMBER}_FULFILLED`
      );

      /** Second dispatched action should deliver response from API */
      expect(store.getActions()[1].payload.data).toEqual(response);
    });

Здесь я тестирую асинхронный action creator который забирает данные с rest endpoint. Я проверяю как оно себя ведет при симуляции удачного ответа API. Я проверяю какие action были отправлены в store, а не то что возвратила функция. Я проверяю очередность action. Также я проверяю, как action обрабатывает полученные данные.

Полный код теста здесь — github.com/morewings/cra-template-quickstart-redux/blob/master/src/features/random/actionCreators.spec.js
Мы немного о разных вещах говорим. Я работаю по TDD, потому пишу тесты, чтобы написать код, но не наоборот, таким образом, мне нужен тест для того, чтобы написать простейший action creator. И наличие такого теста даёт уверенность в том, что экшн будет возвращаться нужный, в том, что завтра другой разработчик его не отрефакторит, сломав логику.

Здесь у вас уже не юнит тест, а интеграционный, с моками ответа сервера и вот этим вот всем. К тому же, внутри него целых два не связанных проверки, плюс ещё замешана логика внутри самой проверки. Три экспекта показывают два независимых теста. Первый про pending, второй про fulfilled. Должен быть ещё и третий тест, который покажет работу с ошибкой в API.

Более того, вы используете redux-promise-middleware и тестируете её работу, а не своего создателя экшена, так что, в данном случае достаточно было протестировать только то, что задиспатчился экшн с типом GET_RANDOM_NUMBER.
У меня, конечно, специфический пример. Но даже в вашем случае, при использовании TDD, я бы использовал такое
expect(store.getActions()[0]).toEqual({
   type: ACTION_NAME,
});

А иначе выглядит как игра в поддавки.
Здесь уже замешан store. Зачем нам тестировать то, что уже протестировано? Т.е. заворачивать в dispatch объект, которые возвращает функция, а потом проверять, что он попал в store. Это и так ясно, так и работает Redux :)
> Причина тут в том, что рефакторинг может приводить к существенному изменению кода. А это в свою очередь может изменить граничные условия, для учёта которых могут потребоваться дополнительные тесты.

Если граничные условия у вас определяются кодом, а не бизнес-требованиями, стоит задуматься — всё ли вы делаете правильно? Да и вообще, правильно ли понимаете, что такое «рефакторинг»?

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


y=(a+b)-c
y=a+(b-c)
НЛО прилетело и опубликовало эту надпись здесь
Ну, вообще-то, у рефакторинга есть вполне четкое определение — изменение исходного кода без изменения внешнего поведения. Если в коде есть ошибки, он не работоспособный, до рефакторинга ещё далеко. Если «рефакторинг» приводит к изменению внешнего поведения, то это не рефакторинг. Рефакторинг должен приводить к улучшению читаемости кода, делать его более лёгким для понимания.

Просто оставлю ссылочку refactoring.com
image

НЛО прилетело и опубликовало эту надпись здесь

Про рефакторинг уже сказали, про xpath пока нет… Глобальный поиск по дереву типа #root div.Agreement div.checkboxWrapper input как раз усложняет "генерацию и адаптацию тестов к изменяемому коду", делает тесты нестабильными и привязанными к конкретной реализации. Поиск по уникальному идентификатору — единственный способ создать абстрагированные тесты, которые не потребуют исправления при рефакторинге, так как иерархичное DOM-дерево не является статичной точной опоры.


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

Мы стали отказываться от redux, потому что тесты писать надо на всё. Относительно примера в статье, стоит заметить, что хранить состояние чек-бокса в redux-store дороговато. Плюс спорное решение в том, чтобы получать состояние чек-бокса прямо в нём. В таком случае тестировать все его состояния сложнее (нужно оборачивать в провайдер и передавать туда порой сложные объекты) и, если вдруг придётся съехать с redux, придётся переписывать такой простой компонент.
Спасибо, дельное замечание. В статье я не стремился показать идеальную архитектуру приложения, а продемонстрировать преимущества, которые даёт Redux, как он повышает уверенность в конечном результате. В каждом конкретном случае следует выбирать инструмент, который лучше подходит для выполнения конкретной задачи.

отличный пост!
для тех кто не знал или боялся применять TDD он будет хорошей мотивацией!

Для 2016-17 бы статья была еще норм, но в 2021… Redux? CRA? export default? Иммутабельность? Тестирование компонентов вместо интеграционных или e2e? Хотя чему удивляться, еще появляются статьи про модалки на jQuery и обработку форм на php. Но выглядит так, будто динозавры повылазили из пещер.


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


{
  "main": "./LicenseAgreement.tsx",
  "types": "./LicenseAgreement.tsx"
}

И import React from 'react' неактуален с 17 версии. Также ручной маппинг по строкам 'agree' некорректен — как минимум нужны текстовые константы, оптимально — подключен стор с локализацией и простым доступом к текстам компонента, так как падающие юнит-тесты из-за изменений в тексте — боль.


Но в целом я бы не рекомендовал ориентироваться на эту статью — желание начинать новый проект с TDD на подобном стеке должно было бы уйти у большинства фронтендеров.

Если у вас перевёрнутая пирамида тестирования, тогда конечно, e2e и интеграционные тесты — ваше всё. Я выбираю более стабильные и быстрые unit тесты.
Стор с локализацией, текстовые константы вообще не имеют никакого отношения к примеру. Я намеренно всё оставил так просто без всяческих усложнений, так как они бы просто увели в сторону от идеи статьи.
Что касается технологий — я не ставил целью показать самый писк моды во фронтенде. Инженерные практики вообще мало зависят от используемых инструментов. Синтаксис импортов/экспортов может поменяться, так же как и навыки писать качественный код следует развивать постоянно, не привязываясь к конкретному стеку. Привычку писать код по TDD нужно вырабатывать, нельзя просто так взять и начать. И перед этим нужно просто научиться писать тесты. Во фронтенд-разработке большинство просто боится (или просто не хотят) писать тестируемый код, в статье я показал, что это очень даже возможно.
  1. Статья называется "Кому с Redux жить хорошо", как я понял из содержимого — основной упор на обзор юзкейсов этого инструмента, а TDD используется как пример. Поэтому считаю свою критику вполне обоснованной, так как к комбинации диспетчер-экшены-константы-редюсеры-селекторы-контейнеры-ручной маппинг-иммутабельность-проброс через props с обновлением родителей — довольно много контраргументов. Это обсуждалось много раз на Хабре, и подавляющее большинство проектов (из тех, в которых я участвовал — все) перешли либо на MobX, либо на локальные стейты+контекст+hooks&функциональщину. Поэтому в статье стоило бы сделать вывод "Кому все-таки хорошо с Redux? Никому", а не "потом навертим Redux Tookilt и будет чуть менее больно".
    Если вы бы хотели, как красиво пишете в комментарии, сделать пример работы через TDD в отрыве от конкретных подходов ("без всяческих усложнений", "инженерные практики", "качественный код", "не привязываясь к конкретному стеку", "нужно просто научиться писать тесты"), то не ставили бы статье такой броский заголовок, и не рисовали бы картинки "архитектуры" редакса и вот этот весь бойлерплейт. Поэтому говорить красивые слова про инженерию, предсказуемый результат и качество кода не стоит — статья в целом не об этом.


  2. Про перевернутую пирамиду тестирования — юнит-тесты (основа пирамиды) — это не про интерфейсные компоненты, которые преобразуются в другую структуру (DOM) и работают в десятках разных окружений в комбинации со слоями позиционирования и стилей. Это про чистые функции (нормализация данных, модификация хранилищ) и редко — про сайд-эффекты. Отрендеренный в виртуальной Jest-среде компонент и то, что ему переданы корректные пропы говорит только об этом, а не дает никакой гарантии работоспособности. Если это защита функционала от случайной модификации другим разработчиком — то да, в этом кейсе работает, но и в равной степени мешает, так как часто приходится править тесты "для галочки". Для корректных типов данных есть TS, который справляется с задачей не хуже, а для всего остального — интеграционные тесты.



Допустим, есть бизнес-задача:


  • при активном состоянии чекбокса Agree кнопка Sumbit доступна, при неактивном — задизейблена.

Под эту задачу по TDD пишется интеграционный тест:


visit('/license')

page.findCheckbox('#Agreement_Checkbox').hasLabel('Agree').notActive()
page.findButton('#Agreement_Submit').hasText('Submit').isDisabled()
page.findCheckbox('#Agreement_Checkbox').click().isActive()
page.findButton('#Agreement_Submit').notDisabled()
page.findCheckbox('#Agreement_Checkbox').click().notActive()
page.findButton('#Agreement_Submit').isDisabled()

Этот код завязан на id, соответственно ему не важна реализация — React, Redux, Svelte, простой html. Также он проверяет, что эти элементы отрендерены, не скрыты стилями, интерактивны, не перекрыты другими слоями. Это как раз концептуальный TDD для автоматизированного контроля соответствия приложения бизнес-требованиям, и если бы вы говорили в статье про это, а не как навернуть в Redux-приложении бесполезные тесты для view-слоя, то код тестов был бы аналогичен.


То, что Jest "стабильнее и быстрее" работает — тут не поспоришь, хотя на хорошей машине headless-браузеры работают очень шустро. Только вот даром такие юниты не нужны, если компонент прост — то его и так легко спроектировать, если сложен — то почти всегда можно раздробить на части, так что эти "react-redux-юниты" и тут не помогут.

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

Немного упросил ваш код: image


  • Код приложения с тестами уменьшен c 370 до 75 строк
  • Число файлов уменьшено с 25 до 5
  • Время сборки с прогоном тестов уменьшено с 30 до 5 секунд
  • Размер бандлов уменьшен с 45 КБ до 30 КБ
  • При этом убрана минификация кода
  • И добавлена поддержка локализации
  • И тайпчек стилей
  • И деплой на GtiHub Pages

Не благодарите.

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

Это напоминает мне ситуацию с abc-гипотезой:
www.gazeta.ru/science/2013/03/30_a_5122709.shtml
Чувак придумал свою теорию для доказательства гипотезы, но ее никто не понял.

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


Надо просто привыкнуть.

Я ветки с упоминанием $mol уже давно просто пропускаю)
Тут было любопытно, вдруг случится чудо и он хотя бы в чужой репозиторий его не потащит.
я так понимаю, использовать html и тем более JSX вместо кода на JS с $mol нельзя?

Redux вышел вместе с хайпом анти хейт движений (толерантность, Блэк лайфс мэта, и тп), я не против толерантности, но реальное отношение разрабов к redux макарошкам сильно негативное, и явно не коррелирует с количеством статей против редакса. Даже когда патриарх Дэн отрекся от своего детища, все ещё есть старообрядцы, которые умудряются запилить статью-простыню про редокс-стильно-модно-молодежно. Все хейт комменты заминусованы (не мудрено), но в контексте статьи, я бы минусовал статью — хватит безкомпромисно насаждать ужасно раздутый подход.

Redux — вполне себе уже устоявшееся явление, у меня язык не повернётся называть его молодёжным и уж, тем более, хайпом :)). К тому же, в статье нет никакой агрессии по отношению к другим технологиям, чего не скажешь про приверженцев Мобикса или вот тех, кого вы назвали в первом предложении.
Да, Redux требует (без RTK) написание большого количества бойлерплейтного кода, но, в то же время, даёт мощный контроль над тем, что происходит в приложении, а так же значительно упрощает написание тестов. У каждого свой путь, здорово, что есть множество альтернативных инструментов, каждый может выбрать то, что подходит ему больше всего.
Redux — вполне себе уже устоявшееся явление

Как и Pascal, Fortran и т.п. во времена динозавров, так вот Redux это тоже давно забытое прошлое. И это не просто так. Если бы он был хороший и удобный, то никто ничего другого бы не использовал по сей день, но увы и ах, он абсолютно топорный, неудачный и ущербный.
Да, Redux требует (без RTK) написание большого количества бойлерплейтного кода, но, в то же время, даёт мощный контроль над тем, что происходит в приложении, а так же значительно упрощает написание тестов.

«значительно упрощает написание тестов» — Я не понял, так вы тестировщик или разработчик?? Похоже всё таки тестировщик. Выбираете инструменты исходя из тестирования, а не исходя из разработки.

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

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

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

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

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

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

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

На Хабр Карьере по слову Redux выдается 88 вакансий, по MobX 19. Pascal и Fortran, действительно, по нулям.
У меня всё.
Вы ориентируетесь по тому хорошая технология или нет по кол-ву вакансий? :D Тогда вам стоит обратить внимание на wordpress, php и т.п. Вы выбрали не тот путь и не ту сферу похоже.
На Хабр Карьере по слову Redux выдается 88 вакансий, по MobX 19
Вроде бы раньше соотношение было более в пользу Redux. Есть еще надежда на светлое будущее. А то не так много вакансий для тех, кто не считает Redux хорошим решением и может нормально разрабатывать без него.

Вместо Pascal следует искать Delphi, который является его более поздней разновидностью. По нему до сих пор есть вакансии. Великая вещь для своего времени. Кстати, разработку Delphi, который оказал влияние на C#, который оказал влияние на TypeScript, вел один и тот же чувак.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.