Если вы как я долгое время считали, что JavaScript – это такой «игрушечный» язык на котором пишут анимашки для менюшек и падающий снежинки на форумах под новый год, а потом очнулись в 2016 году с мыслями WTF: react, flux redux, webpack, babel,… не отчаивайтесь. Вы не одиноки. Материалов по современному фронтенду в сети много, даже слишком много. Под катом вы найдете пошаговое руководство, ориентированное на backend-разработчиков, желающих быть в тренде современного frontend’а.
Итак, нам потребуются: React, React Dev Tools, React-Hot-Loader, React-Router, Thunk, Redux, Redux Dev Tools, Semantic-UI, Webpack, Babel и npm.
На первый взгляд много. Сравним с бекендом: MVC-фреймворк, ORM, Data Mapper, IOC-контейнер, логер, профайлер, очереди, управление конфигурациями, сборка и выкладка… Список можно продолжить, но думаю идея понятна и так: с ростом сложности решаемых задач растет и сложность инструментов. Все чаще мы употребляем термин Web App вместо Web Site, акцентируя внимание на богатых возможностях современных веб-приложений.
Почему именно этот стек?
Если вдуматься и отбросить все лишнее, то единственный ресурс постиндустриальной эпохи, через который можно выразить все остальные – это время. Освоение каждой новой технологии требует затрат времени, а значит более перспективны инвестиции в технологии, которые не устареют в ближайшие пару месяцев. Дополнительный плюс получают технологии с пологой кривой обучения.
React + Redux VS Angular VS Yet Another JS Framework
Только ленивый не сравнил Angular с React’ом (приписав при этом, дескать, сравнение не корректно, Angular – фреймворк, React – библиотека). Пойдем от обратного. Почему бы не выбрать что-нибудь эдакое, типа Vue, Ember или, упаси боже, Elm?
- Поддержка крупных вендоров
- Размер сообщества
Благодаря этим факторам, вероятность выживания Angular и React выше. Простите, другие замечательные хипстерские решения, нам не по пути. Итак, почему React? Лично для меня выбор был не простым:
- Меня пугали jsx-файлы
- Я кое-что умел на Angular 1.x и переходить на другую технологию было психологически не комфортно
- ng2 по-умолчанию идет в комплекте с TypeScript, что мне как стороннику статической типизации ближе
- ng подкупал подходом «работает из коробки». Копаться в многообразии npm-пакетов решительно не хотелось.
Короче, я заставил себя изучить все статьи-сравнилки и написать Todo App на React, что заставило чашу весов склониться в противоположную сторону. Ключевыми факторами для меня стали:
- HTML-шаблоны Angular ужасны и их синтаксис меняется от версии к версии. В React шаблон – это JavaScript, потому что компонент – не более чем View. Сообщения об ошибках в React лучше.
- Как ни странно, TypeScript. При более детальном изучении оказалось, что не все так прекрасно. Во-первых TypeScript – это не полноценный язык со статической типизацией, а транспилер. Это сильно ограничивает возможности использования шаблонов и мета-программирования. Во-вторых, далеко не все npm-пакеты идут в комплекте с d.ts-файлами. Короче, Flow показался проще в прикручивании. В-третьих, у TypeScript есть как ярые фанаты, так и противники. Если фанаты TS сравнительно лояльны к ES6, то обратное – не верно. ES6 получает дополнительное очко к Bus Factor.
Если вам нравится TypeScript, то ничто не мешает использовать его вместе с React. Просто конкретно мне он пока не дал критического объема преимуществ, чтобы заставить меня тратить время на еще один элемент в стеке.
- Доклад Дэна Абрамова про «путешествия во времени». Если ваш опыт в бекенде похож на мой, то вы без труда увидите, что новомодный flux – это CQRS и Event Sourcing «вид в профиль». Вместо проекций – редюсеры, а вместо команд и доменных событий – экшны. А если вы работали, например, с WPF, то разобраться с React – вообще дело пары вечеров.
Да, Redux можно использовать и с Angular, он никак не привязан к React, но для React уже есть react-redux и react-hot-loader. Наверное, для Angular тоже есть, но мейнтейнер Redux’а явно на стороне React.
Для React и Redux доступно два расширения Chrome. Рекомендую поставить оба, чтобы сделать отладку приятной.
Таким образом, связка React + Redux одновременно:
- Более-менее проста в изучении, потому что в основе лежит простая идея ui = f(state => props) и понятна тем, кто знаком с CQRS и Event Sourcing
- Не тащит за собой дополнительных зависимостей
- Обладает лучшим на данный момент Tool Support: IDE и плагины для Chrome
Есть еще всякие ништяки, вроде React Native, но я им не пользовался, поэтому поделиться на эту тему мне, к сожалению, нечем.
JSX
JSX – это не JavaScript. Да, React можно писать без JSX, но проще тогда без React’а. Вообще ситуация с JSX и HTML-шаблонами напоминает мне засилье шаблонизаторов для PHP, самым монструозным из которых был конечно Smarty (этот монстр еще жив). Мне казалось, что люди сошли с ума. Как иначе можно было объяснить желание написать шаблонизатор… для шаблонизатора Perl?
JSX – простой и понятный способ использовать JavaScript в шаблонах. Вам не нужно учить дополнительный ЯП, просто оберните теги в (скобки)
, а код внутри тегов {в другие скобки}
. И все. Да, так просто. Кроме этого React позволяет создавать stateless-компоненты:
const StatelessComponent = props => (<div>{props.title}</div>)
Такая запись короче и лучше читается. Я рекомендую не увлекаться экономией строк и вместо export default props => ({props.title}) использовать чуть менее лаконичное, но безопасное:
const StatelessComponent = props => (<div>{props.title}</div>) StatelessComponent.propTypes = {…} export default StatelessComponent
Во-первых, если вы не передадите параметры, то React недвусмысленно намекнет в консоли, что вы не правы. Во-вторых, WebStorm умеет анализировать PropTypes
и при авто-дополнении заботливо вставит все required props.
Babel
Если вы не поняли на каком языке примеры кода выше, не расстраивайтесь. Это не JavaScript, ну не совсем JavaScript. Это ES6 + JSX. С JSX мы разобрались в параграфе выше – это просто синтаксический сахар для шаблонизации (почти как <?=$var?>
в PHP или @Model.Param
в Razor).
С ES6 ситуация чуть сложнее и запутаннее. Если коротко:
- JavaScript собрали на коленке под нужны тогдашнего интернета, который представлял собой действительно в основном гипер-текст.
- Прошло некоторое время и в сайты начали пихать все что угодно, кроме текста.
- Язык в существующем виде перестал удовлетворять нуждам рынка. Консорциум ECMA стал придумывать всякие новые фичи и стандарты языка, да с такой скоростью, что браузеры не успели все внедрить.
- В сообществе психанули и написали Babel – транспилер из JavaScript в… JavaScript. Ну в смысле из «нового» JS в «старый», который браузеры поддерживают.
Babel умеет транспилить не только JS, но и JSX, что позволяет писать React-приложения на ES6.
Да, есть
React.createElement
. Можно писать на React-приложения и на ES5, но зачем?
Стоит отметить, что ES6 – это не истина в последней инстанции. Некоторые фичи до сих пор являются экспериментальными (например, генераторы) и для их использования потребуются полифиллы (библиотеки, реализующие экспериментальные фичи стандарта). По совокупности причин мы решили отказаться от redux-saga в пользу redux-thunk, хотя и идея диспатчить функции до сих пор не кажется мне изящной (она просто работает).
Webpack
Так, то есть пишем мы на ES6 + JSX, а в бразуере выполняется минифицированный JS. Все это напоминает историю изобретения высокоуровневых ЯП. Люди могли писать более эффективные программы на ассемблере, но предпочли удобство и продуктивность. Раз есть исходники и компилятор (транспилятор в нашем случае), то потребуется и система сборки. Если в вашей пещере было достаточно тепло и уютно, возможно, названия grunt и gulp вам ничего не говорят. Что к лучшему. На данный момент, можно считать (слава богу), что для JS есть только один сборщик – Webpack — оставивший конкурентов позади. Не смотря на то что, конфиги Webpack’а на первый взгляд напоминают некромантские свитки, через какое-то время привыкаешь. Наверное, каждый любитель фронтенда должен хотя-бы раз в своей жизни написать tutorial по настройке webpack, также как каждый фанат ФП – tutorial по монадам.
Что нужно знать про вебпак:
- Вам потребуется кто-то, кто умеет его настраивать
- npm start — для запуска dev-сервера
- npm run build для сборки фронта на продакшн
Вообще Webpack собирает не только JS, но еще и sass, svg, шрифты и вообще все что душе угодно, но я пока еще не готов написать полноценный туториал, так что поищите на просторах интернета.
Npm
У Ruby есть gem’ы, у php – composer, у .NET – nuget. Короче, JavaScript тоже потребовался пакетный менеджер. Изначально npm использовался в nodejs-разработке (отсюда и название -node package manager), а для фронта использовался bower. Потребность в последнем как-то отпала сама собой с повсеместным переходом использованием ES6, Webpack и TypeScript. Этот параграф добавлен лишь для того чтобы отметить, что npm использует файл package.json, внутри которого можно написать:
"scripts": { "build": "webpack --config webpack/config.js -p", "start": "webpack-dev-server --config webpack/config.js" }
Без этих строк npm run build
и npm start
не заработают.
Было бы логичнее вызывать npm build
, а не npm run build
, но эта команда зарезервирована для внутренних целей npm, так что ничего не выйдет.
React-Hot-Loader
Ключ --hot
запускает dev-сервер webpack’а с «горячей заменой». Согласитесь, билдить при каждом изменении – довольно уныло. HMR (hot moudle replacement) делает это за вас. React-Hot-Loader позволяет избежать при этом перезагрузки страницы и потери текущего состояния. Настройка hot-loader’а правда, довольно тонкая работа и вообще фича — экспериментальная и работает не всегда. Особенно сложные отношения у горячей замены с react-router. Но к хорошему быстро привыкаешь и рано или поздно вам захочется написать if(module.hot)
для того, чтобы страница не перезагружалась.
React-Router и Thunk
Основная ниша React’а в Web – это конечно SPA-сайты. А какой SPA-сайт без навигации и общения с сервером. Первую задачу решает react-router. Здесь альтернатив нет. Из неприятных сюрпризов:
- Четвертая версия не совместима с третьей из-за чего у нее проблемы с пакетом history.
- Для hot-reload нужно соблюдать некоторые нюансы, иначе в консоли будут появляется предупреждения о том, что нельзя заменить route. К счастью ошибки достаточно информативные и исправить их просто.
RouterMiddleware
может сломать Redux плагин при совместном использовании.- Не очевидно, что вместо тегов
<Route />
можно использовать JavaScript-объекты и передать их в компонент роутера/>
. Это бывает полезно, при разработке модульных приложений, когда структура маршрутов не известна заранее.
Thunk – это middleware для redux, позволяющее диспатчить функции вместо объектов. Чаще всего используется для запросов к серверу. В компоненте делать запросы – не комильфо. Редьюсеры – вообще дожны быть чистыми функциями. Ничего не остается, как делегировать это middleware.
Альтернатива thunk – redux-saga. Сага предоставляет больше возможностей, но у нее довольно крутая кривая обучения, и она тащит за собой полифиллы для генераторов. При правильном проектировании логики в компонентах нет, а connect к стейту Redux в основном производится через фабричный метод. В общем, мне показалось, что нет большой разницы, как именно управление перейдет к fetch
и будет ли написано yield
или then
. На сайте Redux пример с thunk, так что по совокупности причин сагу я отложил до лучших времен.
Semantic-UI
Раз мы заговорили про SPA-приложения, то кроме навигации и запросов к серверу нужны еще компоненты, которые будут ту самую серверную информацию отображать. Для React есть обвязки Bootstrap, Material UI, Syncfusion Web Essentials (хотя эти обвязки не честные – там внутри jQuery). Наш выбор остановился на Sematic-UI. Решение удалось принять очень быстро – сначала отмели платные компоненты. Material UI не стали использовать из-за обилия анимации (сложнее модифицировать). Остались Bootstrap и Semantic. На Бутстрапе уже пол интернета сделано и в целом, Семантик показался более визуально-привлекательным. В общем, остановились на нем. Сразу оговорюсь, что использование Semantic UI – строго опционально, потому что минифицированная версия весит около 500кб.
Так что разрабатывать фронтенд в 2016 году вполне себе комфортно. Да инструментов много, многие библиотеки не совместимы, новые версии выходят очень часто. Это разумная плата за гигантский скачок в качестве фронтенд-стека.
ссылка на оригинал статьи https://habrahabr.ru/post/326162/
Добавить комментарий