- PVSM.RU - https://www.pvsm.ru -
Статья ориентирована на iOS и android разработчиков, которые уже достаточно хорошо разбираются в своей области и поглядывают в сторону React Native.
Впервые узнав про React Native, я воспринял его как повод для веб-разработчиков вторгнуться на мою территорию (нипазволю!) и заодно испортить хорошо работающий crash-free-60-fps продукт. Так оно и произошло. Конец. Реальная история оказалась длиннее.
JavaScript в мобильном приложении? В голову приходило всего пара библиотек с использованием JavaScriptCore на iOS (эти же библиотеки были причиной 90% падений приложений, в которых использовались) и гибридные приложения “старого образца” (ну это вообще атас).
Гибридные приложения подавали надежду до того момента как ты их попробуешь, после чего начинаешь бежать от них сломя голову и как можно дальше.
Вспоминая неудачные потуги в освоении Xamarin 3 года назад я быстро отказался от идеи использовать React Native.
Стоит отметить что я всегда с радостью воспринимал новые способы написания нативных приложений (от ObjC к Swift, от Java к Kotlin, от Eclipse к Android Studio). Уже много лет занимаюсь iOS и android разработкой в качестве хобби и профессионально. После перехода на новый язык (внутри одной ОС) или IDE я редко возвращался к предыдущему. Казалось бы React Native — логичный следующий шаг, ещё одна новая ступень вверх. Или это шаг назад?
К чему мне учить упрощённый вариант, когда я уже знаю как делать это “по-настоящему”?!
На этот вопрос мне ещё предстояло найти ответ когда компания поставила задачу полного редизайна одного из приложений (в тот момент доступного только на iOS) и выпуска его на android.
Как сделать сразу два дела и написать меньше кода? Напрашивались решения вроде: тонкий клиент, библиотеки на C с вызовом из Swift / Kotlin кода, React Native?
React Native выглядел довольно перспективно из-за возможности сделать библиотеки и затем использовать их сразу на трёх платформах (iOS / android / web).
Перспективно для кого угодно, но только не для меня. Я точно не был счастлив такому повороту. Чувствовал что нахожусь на пике способности к развитию iOS и android и тут меня попросили выбросить все эти знания, как будто я свежий выпускник и опыта у меня 0. Ещё больше я сомневался в том что с React Native можно создать качественный продукт.
Сомнение были обоснованными. Главные проблемы:
Главная скрытая проблема: внутренний блок в моей голове, который мешал увидеть плюсы за кучей минусов.
И конечно React Native — это не только минусы. Есть много хорошего, пишется это намного проще и работает из коробки лучше чем тоже самое на конкретных платформах.
Если отбросить очевидные проблемы, вроде падений и скудных доков, то вот примеры того, с чем пришлось столкнуться:
Ничего удивительного. Это первое с чем придётся идти рука об руку через кровь, пот и слёзы.
Когда я начал вспоминать свой предыдущий опыт frontend-разработчика (до мобильных приложений занимался сайтами), у меня начался вьетнамский синдром: Джонни, JavaScript нас окружает!
Если решите писать приложения на React Native, то рекомендую пройти один из свежих курсов по JS. Необязательно чтобы они были по React или React Native.
В последние несколько лет с выходом стандартов ES6, ES7 и ES8 способ написания кода сильно изменился.
И он стал очень даже ничего.
В первые месяцы очень недостаёт статического анализатора, который есть во всех нативных мобильных языках.
Есть разные утилиты, которые сглаживают его отсутствие, выполняя часть функций
Самым большой вызов здесь будет для начинающих iOS разработчиков.
Этот вызов — отсутствие визуального редактора интерфейса.
Всё делается в коде с помощью JSX [2]-разметки. Технически, эта разметка не обязательна, она помогает увидеть иерархию компонентов. Android-разработчики будут в своей тарелке, заметив сходство с XML.
Одновременно есть понятный вид вьюшек и потенциал для переиспользования.
В iOS нет либо одного либо другого, зависит от того какой метод выбрать (вёрстка в коде или в Interface builder). Да, обе эти проблемы решаемы, но приходится писать приличное количество кода.
В React Native нет этой проблемы.
В Android, кстати, её тоже нет.
Зато Android-специалисты оценят способ передачи параметров из внешних компонентов во внутренние прямо в разметке.
Базовые View здесь — аналог LinearLayout (android) и UIStackView (iOS) с примесью констрейнтов одновременно. Довольно простой способ (по сравнению с констрейнтами) позиционирования элементов.
В React Native нет ни того ни другого.
Конечно они есть под капотом. Напрямую взаимодействовать с ними не получится. Да это и не нужно.
Жизненный цикл всех React Native компонентов полностью отличается от iOS и android, сложно провести какие-то параллели. Если сосредоточиться на отличиях от нативных систем, то:
Большая скорость достигается за счет инкрементальной сборки — пересобираются только измененные модули, а не весь бандл.
Все изменения в JS-коде видны сразу видны в симуляторе. Колоссально ускоряет разработку!
В JS-части React Native из коробки доступно не всё что нужно.
Можно написать нативную часть на обе платформы, сделать JS-обёртку и вызывать её как остальной код. Ничего сложного нет.
Есть большое количество готовых модулей, написанных сторонними разработчиками.
Все модули подключаются через npm [3] (аналог CocoaPods для iOS и Gradle для android), в которых есть нативный код с нужным функционалом.
Функционал реализован силами Facebook.
Работает хорошо и консистентно.
Как частный случай предыдущего пункта.
Самая большая проблема на android — обработать Intent, отличный от диплинка в приложение.
Зависит, конечно, от Intent’а и что необходимо сделать при его получении.
На эту тему можно написать отдельную статью. Стартовая точка — добавить метод createReactActivityDelegate в MainActivity.
Довольно просто получить 60 FPS при прокрутке длинных списков со сложными ячейками.
Производительность всего остального (например — нажатие на кнопку, печать текста в поле) ниже. Заметно при анимированной смене состояния у большого количества элементов. С этим можно легко бороться. Хороший раздел в документации Using Native Driver for Animated [4].
А ещё из коробки нельзя получить нормальное управление жестами и их связывание с анимацией.
Часто проект просто прекращает собираться, например после:
К счастью большинство этих проблем довольно быстро исправляются. Можно добавить скрипт, который чистит все кеши везде, и запускать его когда что-то идёт не так. Помогает решить 98% странных проблем, возникших из ниоткуда. За исключением CocoaPods, тут всё печально.
Самой большой проблемой на iOS было и есть повсеместное желание npm-модулей использовать method swizzling [5].
Множество нативных модулей подключается бинарниками. Понять что несколько независимых модулей свиззлят один и тот же метод не так просто.
Сборка происходит в несколько этапов и на каждом из них может что-нибудь пойти не так.
Одни npm-модули зависят от других npm-модулей и так далее. Если два модуля завязаны на разные версии третьего модуля, то мы сразу получаем warning при установке, в лучшем случае. А в худшем случае warning'a нет, но ничего не работает.
Аналогичная проблема, если npm-модули полагаются на нативные Android-модули с разными версиями.
После чистки кеша могут тихо подгрузиться новые версии. Вроде ничего не делал, а работать перестало.
Очень лёгкий механизм тестирования через библиотеку Jest, идёт в комплекте к React Native. Удобный анализ покрытия тестами — показывает какие строки в тестируемой функции не вызывались ни разу.
Есть библиотеки для UI-тестирования. Пока на деле не пришлось использовать.
Спустя 13 месяцев работы с React Native могу с уверенностью сказать:
Заключительное слово для того, кто сразу начал писать на React Native и по каким-то причинам решил прочесть эту статью, ещё и до самого конца.
Если считаешь что разобрался в теме и у тебя хорошо получается, то пожалуйста, пожалуйста, попробуй себя в роли нативного разработчика.
Автор: 8of
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/284933
Ссылки в тексте:
[1] доки сборщика React Native: https://facebook.github.io/metro/docs/en/configuration.html#content
[2] JSX: https://facebook.github.io/jsx/
[3] npm: https://npmjs.com/
[4] Using Native Driver for Animated: https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html
[5] method swizzling: https://nshipster.com/method-swizzling/
[6] Источник: https://habr.com/post/416097/?utm_campaign=416097
Нажмите здесь для печати.