Быстрый старт на React Native
Какие горизонты открывает React? Single Page Application (и веб-приложения, и десктопные приложения на Electron) — это цветочки. Очень заманчиво выглядит разработка мобильных приложений на React Native. Лозунг «learn once, write anywhere» стоит того, чтобы приложить некоторые усилия. Go!
13 марта объявлено стабильным чудесное решение:
Многие разработчики сталкиваются с проблемой установки и настройки существующих зависимостей React Native, особенно для Android. С помощью Create React Native App нет необходимости использовать XCode или Android Studio, и вы можете разрабатывать для своего iOS-устройства, используя Linux или Windows. Это достигается при помощи приложения Expo, которое загружает и запускает проекты CRNA, написанные на чистом JavaScript без компиляции любого собственного кода.
Как видно, нужно выполнить несколько условий: установить управляющую оболочку Expo на мобильник, запустить тестируемое приложение через QR-код, при этом мобильник должен находиться в одной локальной сети с вашим компом разработчика.
Можно ещё проще. Подключите мобильник USB-шнурком, и выполните:
Оно само поставит оболочку Expo на мобильник и запустит тестируемое приложение. Дальше горячая перезагрузка работает почти так же быстро, как при разработке веб-приложения на CRA. Магия!
На Ubuntu/Windows оно доступно только для подключенных Android/iOS устройств; но на Mac-е работает и вовсе без мобильника — на симуляторе iOS:
Опционально можно установить на комп Expo XDE:
С помощью этого инструмента также можно запускать тестируемое приложение, при этом отображается лог с мобильного устройства — жирный плюс; но горячая перезагрузка работает медленно, видимо приложение пересобирается каждый раз полностью. UPDATE Нужно вызвать меню разработчика (буквально встряхнуть мобилку), и выбрать «Enable Hot Reloading». При этом выключите Live Reload — оба варианта вместе не поддерживаются.
UPDATE Mac не нужен для разработки iOS-версии; просто подключите iOS-устройство и наслаждайтесь процессом на Ubuntu/Windows (спасибо, andreylat).
Пишем первое приложение на React Native. Часть 1.
Сообщество DevSchacht растёт, накапливает контент и завоёвывает преданных читателей. В свою очередь последние всегда желают получать информацию быстро и удобно. А лучше сразу на своё мобильное устройство. Можно сделать сайт, а можно пойти дальше и создать полноценное приложение, которое будет уведомлять о новых статьях, кешировать их и позволит читать там, где нет мобильной связи (например, в метро).
И тут у нас есть два варианта: новый кленовый PWA и старое доброе нативное приложение. К сожалению, PWA пока не работают полноценно на iOS (как минимум до появления сервис-воркеров в Safari). А написание нативных приложений требует знаний незнакомых нам технологий. Но мы фронтендеры и не хотим учить Java и Swift. Мы хотим React, CSS и в продакшен, и благодаря компании Facebook у нас есть всё, для того, чтобы реализовать наше желание.
В этой серии статей мы постараемся шаг за шагом разработать мобильное приложение DevSchacht на React Native и довести его до публикации.
Дисклеймер: автор не является профессиональным разработчиком на React Native. Советы, данные в статье, могут быть не оптимальны — но, как говорится, мы открыты для пул-реквестов
Что такое React Native?
React Native — это фреймворк для разработки кроссплатформенных приложений. Он даёт возможность создавать и использовать компоненты точно так же, как обычно мы это делаем в React, вот только рендериться они будут не в HTML, а в нативные контролы операционной системы, под которую будет собрано наше приложение.
Итак, у нас есть знакомый JavaScript, JSX и CSS (на самом деле это полифил, реализующий подмножество CSS). C JavaScript есть некоторая неприятная особенность: и на Android, и на iOS ваш код будет исполнять движок JavaScriptCore (тот самый, который идёт в комплекте с WebKit). А вот отлаживать код в режиме дебаггера и запускать тесты вы будете в node.js и Chrome, то есть на движке V8.
Инструменты
Среда разработки
Сам я являюсь ярым поклонником WebStorm, это немного тяжеловесная и интерфейсно перегруженная, но потрясающе мощная и удобная IDE на основе IntelliJ IDEA от компании JetBrains. В настоящее время в неё неплохо интегрирован набор утилит для работы с React и React Native.
Когда возможностей WebStorm становится слишком много, а свободного ОЗУ в системе — слишком мало, я расчехляю старый добрый vim. В принципе, никто не запрещает использовать его с React Native, особенно если подключить подсветку JSX-синтаксиса.
Так же, можно дать шанс результату симбиоза Facebook и GitHub — редактору Nuclide. Этот редактор является набором расширений для Atom и позиционируется компанией Facebook как первоклассное решение для разработки на React Native. Честно говоря, в моём случае этот редактор оказался невероятно требователен к ресурсам и я отказался от его использования.
Заготовка
Для разработки нашего приложения воспользуемся заготовкой от Facebook — Create React Native App. Установить её не сложно:
К сожалению, если вы уже установили пятую версию npm, то ничего не получится. Либо ставьте четвёртую версию npm, либо попробуйте yarn — новый пакетный менеджер от Facebook, в котором всё отлично работает (что неудивительно).
Далее создаём каркас нашего будущего приложения:
Тулинг
В принципе, у нас уже есть всё для начала разработки. Однако стоит установить ещё пару полезных утилит, которые упростят нам жизнь в будущем.
Create React Native App поставляется вместе с Expo. Expo — это набор утилит, библиотек и сервисов, облегчающих разработку на React Native. Expo SDK позволяет обращаться к системной функциональности (такой как камера, контакты, локальное хранилище данных и так далее). Это значит, что вам не нужны Xcode или Android Studio и умение писать нативый код. А так же это значит, что благодаря этому слою абстракции, ваш код становится действительно кроссплатформенным.
Более того, вам даже не нужен XCode и симулятор iOS для запуска приложения, с помощью Expo приложение в режиме отладки можно запустить прямо на телефоне. Для этого на телефон нужно установить клиент Expo для iOS или Android.
Так же, для большего удобства разработки, рекомендую установить Expo XDE, существующий в версиях под MacOS, Windows и Linux.
And last but not the least ( последний, но тоже важный): нам нужен хороший дебаггер. По умолчанию в качестве дебаггера открывается Google Chrome. Это неплохо, но недостаточно удобно. Есть сторонние дебаггеры, один из лучших это React Native Debugger.
Так как стандартный упаковщик (или packager — утилита, упаковывающая ваш JavaScript код в бандл) React Native запускается на порту 8081, а упаковщик Expo на порту 19001, то в дебаггере нужно указать этот порт.
Привет, мир!
Итак, всё готово, для того, чтобы попробовать запустить наше первое приложение. Нам надо выбрать, где мы запустим наше приложение. Так как я работаю на MacOS и у меня установлен XCode, то я выбираю симулятор.
Если у вас нет MacOS, то вы можете запустить приложение прямо на устройстве. Откройте клиент Expo и просканируйте QR-код, который выведется после запуска.
Вы должны увидеть на экране следующий текст
Открываем App.js и меняем
Сработает Hot Reload (горячая перезагрузка), и в приложении вы увидите «Привет, мир!».
Что тут происходит? Наш код шаблона выглядит как обычный HTML, но вместо веб-элементов, таких как
является встроенным компонентом, отвечающим за отображение текста.
Вот и всё, что я хотел сказать на сегодня, увидимся во второй части.
React Native для самых маленьких. Опыт мобильной разработки
Однажды, в одной продуктовой команде захотели разработать мобильное приложение, чтобы проверить гипотезу востребованности продукта и его удобства для пользователей. И то, что в команде не было мобильных разработчиков, не помешало. Два фронтенд-разработчика взяли React Native и за три месяца написали приложение. Тестирование гипотезы прошло успешно, приложение продолжает развивается и вызывает интерес других команд в компании.
Изображение из описания инструмента: www.semrush.com/news/position-tracking-on-the-go.
Это краткое описание истории команды Артёма Лашевского, который на три месяца из фронтенд-разработчика стал мобильным. Подробнее, как это произошло, читайте в расшифровке доклада Артёма на FrontendConf 2019: что такое React Native, почему именно он, пошаговая инструкция создания приложения и выбор нужных библиотек и компонентов.
Артем Лашевский — ведущий фронтенд-разработчик в SEMrush и специалист в области информационной безопасности автоматизированных систем.
Зачем нам приложение
SEMrush — международная IT-компания, которая разрабатывает крупную онлайн-платформу для маркетологов. Входит в ТОП-3 платформ для маркетинга и SEO. У компании 5 млн пользователей, 7 офисов на двух континентах, 800 человек в штате и 30 команд разработки.
Каждая команда разработки занимается своим инструментом в рамках платформы. Я работаю в одной из таких команд из 8 человек: два на фронтенде, три на бэкенде, QA, DevOps-инженер и PO. Инструмент, над которым работает наша команда, позволяет пользователям проверять позиции страниц их сайта по определенным запросам в Google. Инструмент помогает проверять позиции по ключевым словам не только своего сайта, но и конкурентов и проводить анализ и сравнение.
Платформа работает в браузере. Запуск мобильного приложения позволит получить конкурентное преимущество, потому что приложение помогает дольше удерживать старых пользователей и повышает конверсию из бесплатных в платных.
Для пользователей приложение повышает удобство работы с платформой. Через телефон клиент может воспользоваться SEMrush там, где раньше был нужен компьютер. Зайти в приложение, увидеть, упал ли его сайт в выдаче Google или поднялся — ключевые метрики всегда под рукой. Если они просели, то уже в веб-версии можно посмотреть детали и понять, как исправить ситуацию.
Наша команда видела потенциал мобильного приложения и решила попробовать его разработать, но мобильных разработчиков среди нас не было. Мы стали сами изучать инструменты и технологии для разработки приложений.
Нативные приложения — первое, на что обратили внимание. Изучив, поняли, что для нас это долго, дорого и неудобно: нужно изучить два стека технологий, дублировать функциональность и тестировать её два раза.
От нативной разработки перешли к изучению WebView (Apache Cordova). У коллеги по фронтенду был опыт разработки на Cordova, поэтому в первом спринте изучения технологий и решений один из прототипов разработали на Cordova.
Но мы хотели что-то современнее — «модно-молодежно», поэтому перешли к кроссплатформенным решениям.
Кроссплатформенная разработка. Рассматривали несколько вариантов: Flutter, Xamarin, Native Script и React Native. Для нас каждый из вариантов имел свой минус, поскольку мы хотели как можно быстрее стартануть:
React Native
Это фреймворк от Facebook для разработки кроссплатформенных нативных приложений. Построен на базе ReactJS, под капотом не использует WebView, поэтому нет DOM API. В React Native нет HTML и CSS, но есть некоторые компоненты платформы в JSX и CSS-like полифилы.
React Native содержит некоторый JavaScript API над нативными компонентами. Это значит, что нативные компоненты имеют некоторый «биндинг» в JavaScript-компоненты на ReactJS. Взаимосвязь между нативным и JavaScript-бандлом осуществляется через bridge с помощью JavaScript API. Поверхностно, это вся архитектура.
Плюсы React Native:
Два способа написать приложение
С React Native есть два способа разработать приложение: использовать Expo или React Native CLI.
Expo. Это слой абстракций — набор инструментов, библиотек и сервисов для быстрого запуска. Это некоторый API, который «из коробки» даёт доступ к возможностям устройства: к камере, геолокации, push-сообщениям.
В Expo есть инструменты отладки и тестирования приложения. Алгоритм простой: устанавливаем на телефон приложение Expo Client, подключаем телефон с компьютером в одну локальную сеть, заходим в Expo на телефоне, открываем разрабатываемое приложение. Все изменения в коде отображаются моментально. Это помогает тестировать и расшаривать на команду.
Взлет на Expo быстрый и стремительный. С Expo не нужны Xcode и Android Studio. Пишем в нашей среде разработки, собираем приложение с помощью сервиса Expo, подписываем и обновляем на лету.
Но для подписи и сборки приложения (и публикации) нужен Xcode или Android Studio. Чтобы протестировать приложение, необходимо сделать сборку и загрузить на телефон, например, с помощью TestFlight для iOS или прямой установки с ПК на телефон. Стандартная схема, но неудобно и долго.
В целом, выбор простой: хотим разработать прототип — выбираем Expo, хотим приложение с перспективой — React Native CLI.
Мы выбрали React Native CLI. В SEMrush мы наверняка захотим писать свои кастомные нативные части, поэтому решающим фактором стал пункт с нативными модулями и сторонними библиотеками с модулями. С React Native CLI старт медленнее из-за большой подготовки, но в дальнейшем возможностей больше.
Многие коллеги, используя React Native, сталкивались с необходимостью кастомизации, и им приходилось специальными командами делать Eject с Expo на React Native CLI. Структура каталогов файлов простого приложения перенесётся с обычного набора JavaScript-файлов по папкам под Android, iOS и JavaScript. Но со сложным приложением возникнут трудности.
Пишем приложение
Примечание. Для переноса готовых веб-компонентов в «не веб» можно написать транспайлер, но обычно проще переписать заново.
Начать писать на React Native можно довольно быстро.
Объект styles создаётся с помощью модуля StyleSheet метода create React Native. Данный объект — это CSS-объектная нотация, упрощенная модель CSS, которой хватает. Для разметки интерфейса используется Flexbox, тоже упрощённый, но его достаточно для выравнивания по горизонтали и вертикали.
Готово — мы написали приложение под iOS. Забегая вперед, уточню, что оно также работает и под Android.
Первое приложение «Hello, World!».
Кроссплатформенность
Мы хотели, чтобы наше приложение работало и под Android, и под iOS. При этом мы хотели иметь возможность делать различные реализации в зависимости от платформы. В React Native для этого есть два способа.
Первый способ — использовать модуль Platform. Например, создаём приложение и задаем высоту в зависимости от платформы. Под iOS высота 200, под Android — 100. С помощью метода Platform.OS определяем, какую платформу использует пользователь.
Метод Platform.select позволяет писать кроссплатформменные компоненты.
Если есть какие-то кастомные решения или ограничения на операционную систему, можем определять версию ОС.
Компоненты
Мы можем реализовывать кроссплатформенные решения, но важна скорость. Поэтому мы двинулись в сторону готовых решений — библиотек компонентов. Исследовали, выделили много больших решений (UI kit) и выбрали NativeBase. Это огромная библиотека с десятком компонентов, 12 000 звезд на GitHub, которая позволяет решать большинство задач.
Пример UI для iOS слева, для Android — справа.
Пишем код один раз, при этом на каждой платформе он выглядит по-своему.
Навигация
Для навигации мы также сравнили несколько возможных решений.
Мы обсудили с коллегами из сообщества React Native проблему, изучили статьи и поняли, что производительность react-navigation и wix/react-native-navigation примерно одинакова. Поэтому выбрали первое решение, а опыт использования только подтвердил правильность выбора.
Код для трех экранов выглядят максимально просто.
Это тот же «Hello, World!», с которого мы начали, — ничего больше.
Нужно больше компонентов
Выбирая итоговый UI kit, рассматривали многие возможные решения: React Native Elements, UI Kitten, React Native Material UI, React Native Material Kit, React Native UI Library, React Native Paper, Shoutem UI Toolkit, Nachos UI, Teaset. В итоге используем некоторые компоненты этих библиотек.
Слева DatePickerAndroid, справа DatePickerIOS.
Например, в нашем приложении можно запросить отчет или график за определенный отрезок времени. Пользователь указывает две даты, чтобы выбрать период. Но на iOS нативный выбор даты неудобен, особенно по-сравнению с веб-версией нашего инструмента.
Нам бы пришлось делать два поля: для начальной и конечной даты. Выбирать даты в одном поле как на Android удобнее, но мы не сможем настроить всё также — кастомизация минимальна.
Мы нашли решение — wix/react-native-calendars.
Справа пример календаря из нашего приложения с цветами компании.
В нём есть горизонтальный и вертикальный календари, детализация по датам, возможность отображения стиля компании, выбор диапазона дат, блокировка выбора определённых дат и поддержка Android и iOS.Удобно, что в решении один интерфейс, — пишем код один раз, без дублирования и переписывания.
Хранилище
В какой-то момент нам понадобилось хранить данные, чтобы показывать их в офлайне или при возобновлении работы. Для этого использовали библиотеку Async Storage (key-value хранилище). Она работает с ключами и мультиключами (запись, чтение и удаление), а для взаимодействия с нативной частью предоставляет JavaScript API.
Данные под iOS хранятся в сериализованном виде. Под Android — например, в SQLite. Как разработчикам нам не нужно об этом заботиться: есть API, храним данные, всё хорошо.
Анимации
Ниже — пример экрана нашего приложения со списком проектов пользователей.
Сокращённая версия реализации.
Выглядит легко, но приходится «костылить»: сдвигать весь контент выше или ниже на iOS. На Android это не нужно. Ещё здесь интерполяция и разные методы из модуля Animated.
Проблема «мерцания» экрана при первом запуске
Мы написали приложение и решили добавить иконку приложения и Splash Screen (или же Launch Screen) — экран приложения, который появляется при первом запуске, если оно выгружено из памяти. У нас экран в оранжевом цвете и с логотипом SEMrush по центру.
В архитектуре React Native нативная часть взаимодействует с некоторым JavaScript бандлом по bridge. Мы столкнулись с проблемой, что в момент запуска нативная часть работает, а скриптовый бандл ещё не подгрузился. Между оранжевым Splash Screen и появлением списка проектов на экране сияла белая пустота (доли миллисекунд).
Потеря связи
Мы хотели разработать дружелюбный и красивый интерфейс, позаботиться об UX и UI. Но когда пользователь ехал в метро, терял связь и обновлял список проектов, приложение показывало только пустой экран. Лучше, чтобы пользователь видел информацию, которая уже была подгружена, и сообщение о проблеме с интернет-соединением.
С работой в офлайне помогла библиотека Netinfo. Сейчас она вынесена в отдельный пакет, поскольку Facebook разгружает React Native, чтобы сделать его легковеснее.
Отладка приложения
Чтобы не получать ошибки после добавления новых зависимостей, особенно тех, что используют нативный код, нужен дебаггер. В React Native он есть — показан на изображении симулятора iPhone.
Для iOS использовали эмулятор из Xcode, в котором можно выбирать версию ОС и устройства. Симулятор под Android — Android Studio.
В диалоговом меню эмулятора есть режимы Debug JS Remotely и Live Reload. Позволяют видеть свойства компонентов, например, CSS-like стили и просматривать вложенность.
В нативной разработке нужно написать код, отправить в сборку, запустить — это долго. В дебаггере же всё как в ReactJS в вебе: включаем Live Reloading и видим пересборку в реальном времени в симуляторе без перезагрузки.
Кроме того, мы используем еще и React Developer Tools, чтобы инспектировать компоненты, смотреть иерархию и изменять их свойства и стили.
Но и этого мало, есть лучшее решение — React Native Debugger.
В нём есть React Inspector, Redux DevTools, взаимодействие через интернет, console-логирование, профилирования по памяти и приложению, просмотр всех actions. В отличии от первых двух двух решений, можно менять стиль в самом React Native Debugger.
Подключение нативных модулей
До текущего момента всё было легко и прозрачно: берём какое-то решение, подключаем, оно работает. Но есть нюанс — следствие архитектуры React Native. Кроме JavaScript части, все библиотеки используют и нативную, которую нужно связать с React Native. Для этого есть команда react-native link, которая автоматически производит все необходимые изменения и линковку нативного кода в проекте.
Но автоматическое подключение работает не всегда, поэтому иногда приходится выполнять изменения нативных файлов вручную. Если в инструкции к библиотеке не описана ручная установка, то подумайте, а стоит ли её использовать, и по возможности избегайте ручной линковки — пару раз мы наступали на такие грабли.
Результат
Изначально мы хотели написать приложение под iOS, но сделали и под Android, причем они выглядят по-разному, как и должны каждый на свой платформе. Переходы между экранами выглядит классно, а у нас примерно 30 экранов (переходов и состояний). Нам удалось избежать реализации кастомных нативных модулей и использовать сторонние решения.
Сроки: на разработку приложения ушло три месяца работы двух человек. С апреля 2019 выпустили еще несколько обновлений с новой функциональностью, приложение развивается, а команды других проектов хотят внедрить в него свои инструменты.
Производительность React Native нас полностью устраивает, потому что нам не нужна была сложная логика и у нас нет большой нагрузки.
Обратная связь: приятно получать благодарности от пользователей за приложение.
React Native подходит для быстрой разработки мобильных приложений и проверки гипотез, даже если вы не мобильный разработчик. Он постоянно развивается, появляются новые функции и библиотеки. Например, год назад не было поддержки 32 и 64-битных архитектур — сейчас с этим проблем нет.
Видите, каких классных результатов можно добиться, если не побояться взяться за что-то, что выходит за рамки привычных задач. Никогда заранее не известно, когда пригодятся знания, которые получил вроде как «для общего развития», но пригодятся они точно. Поэтому одна из задач РИТ++ 2020 — расширить кругозор и дать впечатление об актуальном положении дел в индустрии в целом.
Смотрите программу, находите темы, которые помогут в работе уже завтра, и вопросы, до которых всё руки не доходили разобраться, и бронируйте билеты — билет на онлайн-конференцию можно позволить и без поддержки работодателя, сейчас для физлица он стоит 5900.