Pull to refresh

Comments 84

Create React App — мой выбор! Долго перебирал-сравнивал. Важно, что самый необходимый набор и реализация скрыта. Обновления пройдут безболезненно.

Вы правы, я к этому же пришел, это мое решение по-умолчанию. Но как же серверный рендеринг? ;)

В принципе, обновления Next.js будут примерно так же проходить, там довольно минималистичный API.
Серверный рендеринг не везде нужен. У изоморфного рендеринга по сути дела 2 преимущества — индексация и снижение нагрузки на клиент, если для рендеринга данных требуются дата-процессинг и подобные вещи (аля всякие мудреные чарты с кучей около-реалтайм данных и прочее).

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

В остальном согласен.
В принципе, в данном юзкейсе можно отказаться от заведения сервер-рендеринга: срендерить её один раз и оставить статическим файлом. Заведение SSR для одного маленького кусочка существенно усложняет код без особенной пользы — discuss?
Если на странице есть динамические запросы данных, то один раз через билд процедуру собирать будет мало. В других случаях может сработать.

И вместо того, что вдохновенно кодить, я снова выбираю инструменты. :)

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


Положил взгляд на Electrode. Вроде как всё по феншую. Смотрится несравнимо солиднее, чем Next.js Пока можно попробовать без сервера. Но само наличие сервера радует. Я хочу туда PostgreSQL прикрутить, уж очень камрад нахваливает. Не нашел на этот счет примеров. Конкретно — посредством pg-promise. Ещё не разобрался, но могу предположить, что обнаружу дополнительные бонусы от связки родных клиента и сервера.


Electrode позволяет импортировать CSS напрямую.

Смущают CSS-модули, можно ли от них отказаться без страданий?


Что предлагается для сайд-эффектов? redux-saga я тоже не хочу использовать. Мой выбор — thunk.


Вопросы озвучены. Цели поставлены. За работу!

Про Postgres тут статья была Uber — причины перехода с Postgres на MySQL.

Я лично везде использую promise middleware и thunk, хватает для всего. Saga рассматривал, но мне не понравился API, который как-то тяжеловат и словоблуден, а так же генераторы.
Про Postgres тут статья была Uber — причины перехода с Postgres на MySQL.

Я сидел три года на PostgreSQL давным давно. Это еще и вопрос ностальгии. Никакие доводы не помогут. :)

Любопытства ради, можете рассказать, почему не срослось с генераторами? И еще, если ли большой проект, где promise/thunk покрыты тестами? Удобно ли тестируются? Ну, точнее, так ли удобно, как саги?
Мне просто в свое время показалось дико неудобным, пришлось «смириться» с сагами, ибо rx-стримы как-то совсем перегружено смотрелись. Сейчас же после некоторого времени использования, саги не кажутся чем-то сверхъестественным.
Генераторы лично мне кажутся менее удобными и понятными, чем промисы. А если использовать async/await то все еще более просто.

С тестами никаких проблем, это же просто промисы, из них можно выстроить любую цепочку диспатчей, параллельных, последовательных, любых.
Ну, самое основное отличие async/await от генераторов (хотя работает первое почти так же, как второе) в том, что async/await — по сути, генератор, «размотанный» в промис. Ммм… ну я даже, не знаю, как по-другому сказать. Т.е. когда вы await'ите async-функцию, вы явно выполняете все ее await-точки, тогда как генератор дает вам чуть больше гибкости, и позволяет подсмотреть результат каждой этой точки.

Собственно, идея саг в том, что вы в этих точках не вызываете какие-то функции с сайд эффектами, сервисы и т.п. напрямую, а описываете декларативно «что должно быть выполнено». Это называется декларативными эффектами, которые при прямом вызове генератора не выполняются, их выполняет redux-middleware тогда, когда считает нужным.

Так вот, описываются эти вызовы с помощью простеньких хелперов из пакета redux-saga. Вызов этого хелпера в yield возвращает просто json-описание, что и как должно быть выполнено. Соответственно, не трудно догадаться, что тестируется это все на ура обычным deepEqual. В отличие от тестирования прямых вызовов сайд-эффектов, когда вам нужно замокать все ваше окружение. Т.е. на уровне юнита, вы раскрываете тесту, что этот юнит использует и вызывает. Или даже хуже, что использует и вызывает тот или иной сервис, который использует этот юнит. Или еще хуже и глубже…

Можно кстати провести прямую аналогию с Elm, так как там все ровно то же. Вместо middleware там рантайм, а «вместо» декларативных эффектов — обычные ADT.

Резюмируя, дайте сагам еще один шанс =) Соглашусь, поначалу генераторы вызывают когнитивное отторжение, но только поначалу.
Кстати, попробуйте затранспайлить бабелем async/await в генераторы — удивитесь, насколько все похоже.
А где бы еще почитать про генераторы и redux-saga, посоветуете лучшее?
По сагам лучшим решением будет почитать офф доки, там достаточно внятные и полезные примеры. А вот специализированной литературы нет, кроме статей на всяких медиумах уровня hello-world, так как техника достаточно нова для js, требует ментального сдвига, да и просто не так раскручена, как остальные решения.

А по генераторам, ну… это генераторы, они везде одинаковые, пойдет любая статья. Тут главное уловить концепцию. Функция-генератор при прогоне через .next снаружи «приостанавливается» на каждом своем yield, чтобы через него сначала «выбросить» наружу какое-то значение «справа» от yield, а затем «принять» значение снаружи через .next и отдать «налево». Т.е. у вас появляются новые точки входа вместо обычной схемы «передать аргументы на входе, получить значение на выходе». Функция-генератор может быть представлена в виде «процесса», как конечного, так и бесконечного, если внутри есть while (true). Именно на этих «процессах» и построены саги.

По генераторам штудирую: раз, два.


Кстати, зачем в коде *, я такого раньше не видел:


var ids = {
  *[Symbol.iterator]: function () {
    var index = 0;

    return {
      next: function () {
        return { value: 'id-' + index++, done: false };
      }
    };
  }
};

По сагам что нашёл интересного: раз, два, три, четыре, пять.


Посмотрел на официальный пример и загрустил — как-то слишком многословно. Может есть какие-то улучшайзеры?

А эта звездочка в этом месте не нужна, это ошибка. [Symbol.iterator] — это возможность задать логику прохода по объекту через for..of как будто это коллекция. И обычно там задается полноценный генератор, а не имитация (объект с next). Ну а если уж имитация, то и * не нужна. На MDN достаточно внятно и сжато описано.
как-то слишком многословно.
Ну так в лучших традициях redux :) Смотрите, тут опять та же история, возможно вам все эти запросы в саги выносить и не нужно. Возможно хватит и контейнера. Саги просто позволяют поднять обработку синхронизации этих запросов на уровень выше, чтобы ни ваши контейнеры, ни редьюсеры не пытались друг с другом как-то общаться, чтобы синхронизироваться. Сага — это хорошее место для длинных транзакций из нескольких запросов (например сходить по нескольким урлам) с возможностью легкой отмены или рейсов. У них там в доках хороший пример про авторизационный флоу — когда у вас может висеть запрос на login, а тут внезапно logout прилетел. Как бы это решалось в стандартном редаксе? ну скорей всего какими-нибудь флагами в сторе. А нужны ли они там? Не нужны, так вот саги позволяют заинкапсулировать такую логику на уровне выше, чем лежат редьюсеры. В них же можно до бесконечности спамить всевозможные экшены, читать из стора через готовые селекторы, которые уже используются в контейнерах, да много чего.
На сагах вы можете описывать не только такие процессы (они обычно watcher'ами зовутся) но и обычные сервисы, например для похода в api. И в этом сервисе вы можете за-put-ать (хм, интересное словечко получилось) экшен SESSION_EXPIRED, который обработается редьюсерами для очистки каких-нибудь sensitive-данных, а так же вотчером авторизации, который вызовет экшен редиректа на логин. И это все прекрасно тестируется без каких-либо моков.
Более того, что самое главное, экшены у вас остаются «тонкими», чистыми и декларативными, как и подобает CQRS+ES (подобию).
comerc Кстати, если вам инетересно поподробнее почитать про CQRS+ES, могу посоветовать вот эту книженцию. Там по ссылке ее даже скачать можно. Дельная вещь, хотя, сознаюсь, я ее все никак не дочитаю :)
Там упоминаются process managers, чем, собственно, саги и являются.

Про многословность я наверно преувеличил. Ниже пример практически построчного переноса сайд-эффекта из под redux-thunk на redux-saga. Посмотрите, пожалуйста, что тут можно улучшить?


redux-thunk
const save = () => (dispatch, getState) => {
  const clearPost = ({ searchHub, errors, isSubmitting, ...result }) => result
  const state = getState()
  const errors = {}
  Object.keys(validators).forEach(key => {
    const validate = validators[key]
    const error = validate(state.postForm[key], state)
    if (error) {
      errors[key] = error
    }
  })
  if (!isEmpty(errors)) {
    dispatch(setErrors(errors))
    dispatch(appActions.setMainError('Исправьте ошибки в форме'))
    return
  }
  if (state.app.mainError) {
    dispatch(appActions.setMainError())
  }
  dispatch(setSubmitting(true))
  axios
    .post('/post/', clearPost(state.postForm))
    .then(response => {
      const post = response.data
      dispatch(postsActions.setPost(post))
      dispatch(push(`/post/${post.id}/`))
    })
    .catch(error => {
      dispatch(appActions.setMainError(error.toString()))
    })
    .then(() => {
      dispatch(setSubmitting(false))
    })
}

redux-saga
function* saveSaga(action) {
  const clearPost = ({ searchHub, errors, isSubmitting, ...result }) => result
  const state = yield select()
  const errors = {}
  Object.keys(validators).forEach(key => {
    const validate = validators[key]
    const error = validate(state.postForm[key], state)
    if (error) {
      errors[key] = error
    }
  })
  if (!isEmpty(errors)) {
    yield put(setErrors(errors))
    yield put(appActions.setMainError('Исправьте ошибки в форме'))
    return
  }
  if (state.app.mainError) {
    yield put(appActions.setMainError())
  }
  yield put(setSubmitting(true))
  try {
    const response = yield call(axios.post, '/post/', clearPost(state.postForm))
    const post = response.data
    yield put(postsActions.setPost(post))
    yield put(push(`/post/${post.id}/`))
  } catch (error) {
    yield put(appActions.setMainError(error.toString()))
  } finally {
    yield put(setSubmitting(false))
  }
}
Ну, что бы я в первую очередь убрал из саги — доступ ко всему стейту целиком. У вас (скорее всего) уже есть селекторы для контейнера формы, переиспользуйте их.

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

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

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

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

Далее, у вас в try лежит слишком много логики, а catch один. То есть, если у вас свалится не сам запрос через axios.post, а, например реакция на setPost или еще хуже push, вы поймаете не ту ошибку (нужно помнить, что реакции на эти экшены выполняются синхронно в текущем контексте) и потеряете предсказуемость работы вашего приложения. Fail fast, все дела. Так что в try я бы обернул только yield call, а в catch бы вышел из генератора через return. И finally тогда не нужен, эта логика пишется просто в тело генератора.
С pg-promise все очень просто ;) Если застряните — есть масса саппорта, включая форум: https://gitter.im/vitaly-t/pg-promise

Можно и на русском тут спросить: https://gitter.im/vitaly-t/russian, или на StackOverflow где я всегда отвечаю.

Я автор pg-promise ;)

Это был ключевой момент выбора, что автор — свой человек. Спасибо!

Жир. Архитипы скрывают реализацию, как и в Create React App.


Только я так не понял, как подключить в WebStorm из архитипа .eslintrc, пока просто копирую в проект.

В шторме же можно указать прямой путь до конфига, даже из нод-модулей. И последние eslintrc вроде должны поддерживать extends
Архетипы, в отличии от CRA, конфигурируемы.
.eslintrc можно экстендить

из архетипа electrode-archetype-react-app-dev выдрал


.eslintrc-node (для сервера)


---
extends:
  - "walmart/configurations/es6-node"
parserOptions:
  # this is not in the Walmart default configuration, for fairly good reason:
  # V8 (and thus Node) does not support ES6 import syntax. Server-side code
  # is transpiled, but this is not reflected in tests.
  sourceType: "module"
rules:
  "strict": ["off", "global"]
  "no-process-exit": ["off"]
  "func-style": ["off"]

.eslintrc-react (для клиента)


---
extends:
  - "walmart/configurations/es6-react"
globals:
  window: false
  document: false
  ReactElement: false
rules:
  "react/jsx-boolean-value": "off"
  "react/jsx-closing-bracket-location": "off"
  "react/no-string-refs": "off"
  # disable invalid rules from walmart default configs:
  "react/wrap-multilines": "off"
  "react/jsx-wrap-multilines": "error"
Create React App это не фреймворк, а обычный генератор кода. И вообще термин фреймворк в отношении реакта неуместен.
И вообще термин фреймворк в отношении реакта неуместен.

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

Да. Даже в русской вики минимум два.

Create React App это как раз вполне фреймворк, т.к. по определению это каркас или структура, облегчающая разработку. В более широком смысле — набор разноплановых библиотек особым образом связанных вместе. Уж точно не генератор кода, Yeoman — вот генератор. Реакт — не фреймворк, в этом Вы правы.
А Yeoman разве на выходе не дает вам каркас и структуру облегчающую разработку?
Как создается проект с помощью create-react-app?
create-react-app my-app

Читаем что написано в readme.md на github
It will create a directory called my-app inside the current folder.
Inside that directory, it will generate the initial project structure and install the transitive dependencies:

А тут написано что это утилита которая генерирует структуру проекта.

Как создается проект с помощью Yeoman?
yo шаблон-реакт-вебпак-и-все-что-необходимо

На выходе имеем так же организованную структуру проекта, где так же достаточно набрать npm start и все взлетит.
В чем отличия? Следуя вашей логике Yeoman это тоже фреймворк всех фреймворков.
Ладно. Create React App — генератор приложения на фреймворке React Scripts :) но поскольку никаких других приложений, кроме как на React Scripts, он не умеет генерировать, то вся эта связка условно названа фреймворком.
Create React App самый простой для понимания в начале, но он вообще не дает никаких средств для модификации.

Всё же даёт. create-rect-app состоит по сути из двух частей: собственно утилита создания приложения и react-scripts. И во время создания, и позже можно изменить "коробочный" набор на любой сторонний или свой форк, включив всё что нужно и исключив ненужное, прежде всего в конфиги вебпака и бабеля. Если речь о разработке "на потоке", когда приложения создаются часто, но целевые конфиги одинаковы, то очень удобно, стандартизирует процессы разработки и инструментарий в команде.

В сравнении с остальными — не дает. Конфиг вебпака же нельзя менять без eject, следовательно способов модификации довольно мало. Про форки и тд речь специально не идет, иначе бы пост раздулся раз так в 100. Так что упрощение сделано сознательно.

Всё же это штатная возможность указать конкретный набор скриптов

За статьи по React-у платят деньги? :)
Если бы ))) я проводил исследование в рамках проектной деятельности и решил поделиться результатами.
За программирование на не-React'е не платят деньги?
Эээ, статья != программирование :)
> Create React App не дает модифицировать конфиг Webpack'а, так что здесь пролет

А как же eject? :)
А зачем тогда Create React App, если делать eject? Проще уж с нуля самому все писать или пользоваться другим фреймворком. В статье об этом было замечание.

Чтобы создать общую структуру папок и конфигов, где уже почти всё что нужно настроено и только донастраивать.

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

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

Eject? Вы шутите. Он же ничего не умеет особого, вам придётся кучу всего добавлять руками, причём в каждом новом проекте. Возьмите лучше тогда NextJS если нравится без конфигурации, или Electrode, там есть генератор, чтоб руками не писать и не копи-пастить. Статья же ведь именно об этом. Нельзя замыкаться на одном решении.

Создаешь приложение с create-react-app, разрабатываешь его пока не уткнёшься в ограничения, а дальше решаешь или делать свою ветку скриптов, или использовать стороннюю (например есть готовые с поддержкой stage-0 и less/sass, постоянно синхронизирующиеся с оригиналом), или сделать eject.


Тот же кодогенератор по сути, набрасывающий основу проекта.

Самый разумный подход (не только в программировании).

Меня вдохновил Electrode на пару дней. Но вернулся обратно на CRA. И продолжаю фигачить на скорость. Ограничение инструментария повышает продуктивность. Парадокс.

Но всё равно нет «пролета», как вы написали.
Без eject пролёт, редактировать же нельзя, как в Next или Electrode. А после Eject жизни нет ;)

Зря вы наговариваете на Next.js, что там роутинг плохой.
Там же на серверной стороне можно юзать express https://github.com/zeit/next.js/blob/master/examples/custom-server-express/server.js
И с помощью него парсить такие пути /items/:id и всё прекрасно.


Препроцессоры для CSS там тоже есть https://github.com/zeit/next.js/tree/master/examples/with-styled-jsx-postcss — подключайте PostCSS плагины, какие хотите

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

PostCSS плагины это все же не полная поддержка любых препроцессоров.
PostCSS это не препроцессор.
JFYI:
PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.

Plugins

Better CSS Readability
— precss contains plugins for Sass-like features, like variables, nesting, and mixins.
А что с кроссплатформенностью?
Есть возможность собирать «из коробки» электрон — кордову?
Одно другому вроде как не помеха.

*электрод


Только зачем, когда есть React Native?

Разумеется, есть много чего кроме реакта.

Но вопрос был по статье «Что взять за основу React приложения», чтобы собирать приложения также и для мобильников и для десктопа.

Один мальчик хотел написать мобильное приложение на Cordova. Потратил $130 долларов, и получил тормознутый прототип из трех функций через полгода. Показывать такое потенциальным инвесторам просто стыдно.


React Native — это лучшая основа React-приложения для мобилок.

А другой мальчик просто набрав npm run build:cordova через пару минут получил готовую мобильную версию своего реакт приложения, которая сейчас успешно функционирует.

Интересно, а на что конкретно полгода то ушло ?)

На офис в Черногории, зарплата: PM, аналитик, дизайнер, два разработчика и два тестировщика.

Взял бы сразу React Native, и ничего бы этого не потребовалось?

Кстати, на нем десктоп приложения под винду делать можно? Нативно, или с электроном подружить как-то?

Поправка — килодолларов.

Что лучше всего подойдет для проектов на основе Django/Python/REST/I18N — Next.js, Electrode или свой кастом лучше собирать. Сделал свой выбор в пользу ReactJS и теперь стоит задача в ближайшем будущем переписывать интернет-магазин с поддержкой мультиязычности и с полным использованием REST (Django REST framework, GraphQL и т.д), изоморфизмом и для дальнейших проектов. Теперь вопрос в том как это все связать, что взять за основу, чтобы в дальнейшем было как можно меньше головняков в ходе разработки и поддержки. В общем практики нет, поделитесь своим опытом с сочетанием Django/I18N/REST/ReactJS и т.д., какие инструменты выбрать?
Решать Вам на основе Ваших требований, серебряной пули не существует.
А какой лучше и проще вообще как для новичка по Вашему опыту выбрать — Next.js, Electrode. Я застопорился на том что инструментов и библиотек много, в статьях и гайдах больше пишут про одно и тоже абсолютно по своему и по разному, из-за чего мало что понимаешь и в голове плохо укладывается как это объединить и подружить. Но с другой стороны хочется инструментария из коробки, единой архитектуры пускай и с ограничениями, теперь только остается сделать выбор Electrode или Next.js, чтобы в этом случае посоветовали как для начинающего?

Create React App, прекрасен тем, что нет ничего лишнего — сел и поехал.


Когда в Create React App станет тесно, перенести в Electrode — никаких проблем, реализация окружения скрыта точно так же, как и в Create React App. Но добавятся: SSR, изоморфность, утилиты.


I18N — мне нравится такое.


GraphQL (Relay) попробовал, это кошмар. Redux — окончательный правильный выбор! :)


Остальное из моего набора: Redux-Form, Redux-Auth, Axios, Redux-Promise-Middleware, Redux-Thunk, Reselect, Redux-Act, Immutable-JS, Material-UI, React-Select.

Спасибо! Теперь я так понимаю что по своей структуре Electrode больше совместим с Create React App, а на Next.js сложней будет перенести, но по нему больше документации. Я думаю может быть начать для практики с Create React App а дальше перенести если мало функционала будет на Electrode или Next.js. Или в принципе можно начать сразу с Electrode или Next.js если с нуля все изучаю. Для меня сейчас главное определиться с чего начинать или попробовать и то и другое, а затем уже определиться что больше по душе. Но в Electrode получается что в начале кошмар с первоначальной настройкой, зато больше свободы и возможностей по кастомизации и расширению, в Next.js легкий старт, меньше головняка в настройках, больше автоматизации но за это расплата — ограничения.
Ну да как-то получается :), самое главное что теперь знаю с чего вообще можно начинать, т.к. основная проблема была — это изоморфизм и способы его отдельной реализации, ну и советы знакомых которые пишут на React по кастому (бойлерплейты + webpack) ни к чему не приводили, один совет и ответ что можно только часть сделать, например поиск и какие-то фильтры, но полностью писать — это бредовое дело и самоубийство.
Как-то получилось что из моего окружения никто-ничего про изоморфность приложений на React не знали и с пеной во рту доказывали что типа зачем это, что поисковики и так уже научились индексировать, но покопавшись на просторах гугла я понял что все не так радужно, но вот конкретных решений да еще из коробки не находил. В общем буду разбираться :)
Огромное спасибо, будем учить и разбираться :)
На днях разбирался с Relay — это чудовищная мерзость. Но я нашел прекрасное решение Apollo: https://github.com/kirill-konshin/react-ssr-playground/tree/master/graphql, вот моя демка, я скрестил демо-блог для GraphQL с сервером и клиентом на Apollo.
А какие еще существуют известные и стабильные решения кроме Electrode и Next.js для основы React приложений?
Как показывает практика, лучшее решение — понимание принципов работы стэка на реакте и вебпаке на низком уровне. Чем глубже это понимание, тем лучше, так как рано или поздно вы 100% столкнетесь с ситуацией, когда коробочное решение будет вам жать. И гнуться оно будет очень с трудом.

Для старта и CRA, и Next.js, и Electrode, и <все, что угодно> — хороший выбор, но я бы все-таки рекомендовал инвестировать время, чтобы разобраться, как работают эти инструменты на низком уровне. После этого у вас не возникнет проблем ни с в выбором технологии обработки сайд-эффектов, ни с SSR, ни с менеджментом стейта, ни с настройкой HMR, ни с ручным развертыванием удобного инструмента для разработки компонентов а-ля react-storybook, ни с чем-либо еще.

Да, это требует времени, но, да, это того стоит.
Да, Вы правы, я похожий путь проходил когда работал HTML/JS верстальщиком, понадобилось время чтобы осознать как обрабатывает браузер внешние/внутренние отступы и прочее, или как было тяжело когда привык только к Twitter Bootstrap (собственно говоря меня сразу за него посадили и сказали что тебе больше не надо знать), а когда понадобилось написать проект на фрилансе чисто в ручную, я понял что ничего не знаю, было и смешно и обидно.
Sign up to leave a comment.

Articles