Компания
139,66
рейтинг
15 февраля в 10:24

Разработка → Исполнит ли React Native мечту программиста: единый код для web, android и ios?

Писать код – сложно. Писать код для нескольких платформ – еще сложнее. Программисты это знают, и последние двадцать лет идеи «универсального всемогутора» будоражат умы и воплощаются в разные технологии. Начиная от Java и заканчивая phonegap разработчики очень хотели, чтобы один раз написал и везде работало. Но не складывалось.

А потом facebook сделал ReactJS. Чтобы чат себе починить. И сложилось. Идея сборки интерфейса из javascript “кубиков” оказалась настолько хороша, что facebook портировал фреймворк на мобильные платформы, сделав сначала React Native для iOS, а через полгода и для Android. Сможет ли технология, пришедшая из веба, сделать то, что не получилось у таких монстров, как Java и .NET?


Давняя мечта: write once, run anywhere


Кроссплатформенная разработка стала популярна совсем недавно. Еще пятнадцать лет назад слово «программа» было синонимом «программа под windows». Подавляющее большинство компьютеров работали на windows. В параллельном мире энтерпрайз решений жили HP-UX (более известное как «чпукс»), серверный линукс и джава. В другом параллельном мире – макось с фотошопом и иллюстратором. Миры не пересекались, программы создавались под конкретные платформы и кроссплатформенные решения были скорее курьезом, чем необходимостью.

А потом случилось несколько вещей. «Выстрелили» мобильные платформы, выросла популярность маков, кардинально упростилась покупка и аренда софта. Программы начали использовать все, а не только «компьютерщики». И неожиданно оказалось, что давний слоган Java “write once, run anywhere” стал очень актуален. Огромному количеству компаний, начиная от банков и заканчивая старбаксом, понадобились приложения. Желательно – сразу для всех актуальных платформ. Крайне желательно подешевле. И совсем хорошо, если прямо сейчас.

Мечте мешают design guides и скорость выполнения


Разработчики было стряхнули пыль с проверенных инструментов, но оказалось, что не все так просто. Подавляющее большинство технологий кроссплатформенной разработки, доступные на мобильных платформах, сами рисуют пользовательский интерфейс. Отчего он, во-первых, выглядит чужеродно. А, во-вторых, тормозит. Добавим к этому «протекающие абстракции»: любое сложное приложение рано или поздно выходит за рамки кроссплатформенного фреймворка и приходилось расширять его «родным» кодом, что часто приводит к проблемам взаимодействия между расширением и самим фреймворком.

Фреймворки и библиотеки, призванные решать эту проблему, начали плодиться как грибы после денежного дождя: Appcelerator, Phonegap, Xamarin, FireMonkey, NativeScript. Но особую популярность никто не завоевал, а в интернете стали появляться статьи вида «Как мы начали делать банк-клиент на название фреймворка и через год выкинули его, перейдя на натив».

React приносит адаптивный дизайн из веба в мобайл


И тут, в середине 2015 года, Facebook представляет React Native. На первый взгляд, ничего нового. JavaScript, из которого можно создавать «родные» элементы пользовательского интерфейса как на iOS, так и на Android. У Appcelerator такое уже было много лет.

Дьявол скрывался в деталях. Сборка интерфейса «из кубиков» и заимствованный из веба «адаптивный» подход к дизайну позволили сделать интересную штуку. Используя React, интерфейс верстается семантически, как в вебе. Вместо того, чтобы оперировать элементами интерфейса ios или android, дизайнер создает интерфейс из логических компонент: «экран», «заголовок», «список», «кнопка». А уже сверстанный интерфейс доводится напильником до конкретных платформ: несколько строчек кода превращают компонент «прогресс» в набор HTML тегов для веба, ProgressBarAndroid для android и ProgressViewIOS для ios.

Такой подход очень удобен: вначале интерфейс быстро верстается из универсальных блоков, а затем дорабатывается под каждую платформу только там, где это действительно надо. Это удивительно напоминает адаптивную верстку, когда вначале верстается универсальный «резиновый» интерфейс, а затем с помощью @media дорабатывается под экран телефона, экран планшета и большой экран.

Прототип приложения теперь можно сделать за пару дней


В качестве примера посмотрим на тестовое приложение для нашего React Native SDK. С помощью SDK можно совершать и принимать обычные или видео звонки, включая бесплатные peer to peer. А приложение показывает, как им пользоваться: окно логина, окно ввода номера или имени, россыпь кнопочек вида «позвонить», «включить видео», «отключить микрофон» и тому подобных. Если посмотреть на исходник, то мы увидим один код, работающий на обоих платформах. Отличается код только там, где мы сами этого захотели. К примеру, используется нативная версия переключателя, поэтому его имплементация разделена на два файла: ColorSwitch.ios.js и ColorSwitch.android.js

Демо приложение было сделано за два дня. Сразу под ios и android. А если мы захотим сделать версию для веба, то это займет от силы еще день (да, web sdk у нас есть и да, он может звонить из браузера благодаря магии webRTC). Все что нужно будет сделать – это заменить элементы пользовательского интерфейса на div’ы и поменять несколько вызовов sdk, которые отличаются между веб и мобайл версией.

<View style={styles.settings_table}>
  <View style={styles.settings_switch}>
    <Text style={styles.settings_label}>Peer-to-peer</Text>
    <ColorSwitch defaultValue={settings_p2p} valueUpdate={(value) => {settings_p2p = value}}/>
  </View>
  <View style={styles.settings_switch}>
    <Text style={styles.settings_label}>Video</Text>
    <ColorSwitch defaultValue={settings_video} valueUpdate={(e) => this.videoSwitch(e)}/>
  </View>
</View>

фрагмент кода отсюда

Все ли так гладко на практике?


С каждым месяцем все больше компаний используют ReactJS и React Native. Тем не менее, технология еще очень молодая (android версии всего несколько месяцев от роду), и все «детские болезни» идут в комплекте.

В первую очередь хочется отметить малое количество элементов интерфейса, которые доступны «из коробки». Полтора десятка универсальных и по десятку специфичных для ios и android. Можно легко «обернуть» любой нативный элемент, но это потребует знаний java, objective-c или swift. Альтернативный вариант – использовать один из сотен созданных энтузиастами элементов, доступных на github. Но open source специфичен – иногда проблем от небрежно написанных элементов больше, чем если делать их самому.

Молодость технологии также ограничивает выбор доступных библиотек и биндингов. На момент анонса React Native у нас уже давно были нативные sdk для ios и android. Пользуясь этим, мы сразу приступили к портированию и первыми запаковали webRTC в React Native. Но все равно это заняло довольно много времени: пока изучишь документацию, пока напишешь код, пока все протестируешь, пока continuous integration настроишь – для серьезных библиотек это может быть вопрос не одного месяца.

Скорость развития фреймворка тоже не всегда играет на руку разработчикам. При обновлении на последнюю версию у нас неожиданно перестало воспроизводиться видео, при этом в логе не то что ошибок – даже предупреждений не было. Долгое копание в коде показало, что авторы «всего лишь» перенесли в другое место ReactProp для Android. Такие изменения, конечно, случаются не часто – но все еще бывают, особенно для версии под Android.

import com.facebook.react.uimanager.*;
import com.facebook.react.uimanager.annotations.ReactProp;
public class VoxImplantViewManager extends SimpleViewManager<VoxImplantRendererView>


Выводы


Технология очень перспективная, но молодая. Из прямых конкурентов я могу назвать “windows universal apps” от Microsoft с похожей концепцией семантической верстки интерфейса, недавно усиленной технологией continuum. И “Xamarin.Forms”, предлагающий похожее решение с «универсальными» и «платформо-специфичными» элементами интерфейса. Но у React есть перед ними ряд преимуществ: web как одна из платформ, сверхпопулярный JavaScript, не менее популярный тулчейн node.js, бесплатность, поддержка facebook и “hot reloading” из коробки.

Можно сказать, что сейчас React Native можно использовать для быстрого прототипирования мобильных версий ваших веб приложений. Причем если веб приложение уже написано на ReactJS, то скорость переноса возрастает в разы. Создание сложных приложений с публикацией в сторах уже возможно, это хорошо видно в галерее. Но будьте готовы к тому, что финальное «доведение до ума» затянется и потребует лезть в java и objective-c.

P.S. А чат они себе так и не починили. Но там, походу, и правда место проклято.
Автор: @eyeofhell

Комментарии (42)

  • +10
    уберите пожайлуста эти ужасные красные заголовки.
    • +2
      Это было просто за гранью добра и зла.
  • +2
    А ещё можно было сделать мигающие заголовки…

    ну а с точки зрения "“windows universal apps" там как раз веб вполне может быть одной из платформ. Более того, можно собрать приложение состоящие, по сути, из одного единственного урла. Другой вопрос, что UWP не являются кроссплатформенными.
    • +1
      А ещё можно было сделать мигающие заголовки…
      Вспомился тег marquee… чтоб уж для полного погружения в атмосферу веба конца 90-х, начала 00-х
  • +5
    А почему вы один раз упомянули что у Appcelerator есть абсолютно все то же самое, да еще и не один год, а в конкуренты его не записали? У него тоже есть, цитата, «web как одна из платформ, сверхпопулярный JavaScript, не менее популярный тулчейн node.js, бесплатность, поддержка facebook и “hot reloading” из коробки». И сообщество большое. И marketplace
    • 0
      Потому что у него не компонентная модель. Там по старинке, как было в Qt, Gtk, wxWidgets и иже с ними.
      • 0
        Минуточку, там есть виджеты и модули. Это не компоненты в том понимании, в котором они есть в реакте?
        • +2
          Это не компоненты в том понимании, в каком они есть в реакте. Весь реакт построен на том, что вы собираете пользовательский интерфейс из кирпичиков, которые затем дробите и специализируете по необходимости. Каждый кирпичик содержит отрисовку, мининмум логики и immutable модель работы с данными. Фреймворк сделан с расчетом на то, что эти кирпичики будут переиспользованы и в рамках одной аппы, и в рамках разных апп. Вы один раз сделали кнопку "купить" с символом доллара и затем используете ее везде.

          В титаниуме тоже так можно! Просто это займет больше усилий :). Вообще, почти на любом фреймворке можно реализовать что угодно, я рассматриваю исключительно на что авторы его "затачивают" и что делать проще всего. Аппселератор — она про "батарейки", бэкенд, аналитику, покупки, инфраструктурыне вопросы — все вот это там очень сильное.
          • 0
            https://github.com/yuchi/react-titanium

            По сути, легким движением превращаем Titanium в React Native. Наткнулся прям вот сегодня.
            Единственная проблема, что плагин «titaniumify» у меня не собрался, т.к. одна из его зависимостей (вроде, некий nan) не дружит с нодой >= 4, а у меня 5. Временно обошел тем, что собираю проект gulp'ом из ES6 в ES5. А всё остальное, на первый взгляд, работает.
  • +5
    Два года назад надо было сделать win8-приложение. Ничего военного, навороченная читалка и большая база книг. Повелся на золотые горы от MS; поленился въезжать в xaml, и выбрал html5. По прошествии двух лет на Javascript остался только UI, и сейчас готовимся к финальному броску.

    Удар по производительности и дичайшее потребление памяти не оправдывает ничто.

    Больше бледнолицый на эти грабли наступать не будет.
    • +2
      2 года прошло.

      Сравнивал на своём старом пятом яблофоне экзампловые приложения на Ионике и Нативном Реакте. Реакт и правда работает со скоростью нативного, так что я даже не знаю чем вы недовольны.
    • +1
      А скоро, возможно, кроссплатформенный perspex станет подходящим для многих xaml приложений.
  • 0
    Fuse еще хорош
  • +1
    Simple native doesn't fit our scale
  • +1
    При всех плюсах Реакта, довольно раздражает то, что для многих на нем свет клином сошелся. Не Реактом единым решается декомпозиция на компоненты. React хорош когда нужно пре-рендер вида на сервере сделать и в кэш положить, в остальных случаях куда более интересно выглядит Polymer, который также вполне хорош в содружестве с Cordova.
    • 0
      react native — это javascript обвязка вокруг нативных элементов(за счет чего достигается скорость), в случае polymer + cordova, у нас опять старое доброе приложение, которое работает через view, ну и далее все проблемы, тормозит, блокирование главного потока пока ui не отработает, ну и далее по списку.
  • 0
    Автор, ваш стиль подростка-фанбоя дискредетирует технологию.
    • +4
      Критикуя — предлагай. Компания платит мне зарплату, чтобы я мог тратить рабочее время на анализ технологий и писать обзорные статьи на Хабр. За это ожидается, что я буду крафтить привлекательные для широкой аудитории заголовки и писать в стиле, который привлечет максимум внимания.

      Полагаю, все хабрапользователи благодарные вам за статьи о ES6. Сам с удовольствием читаю. Если считаете, что мои статьи дискредитируют React Native, что ж — напишите лучше, я буду первый вам за это благодарен. Концепция "либо делать очень хорошо либо не делать вообще" меня не привлекает.
      • 0
        У меня переводы, а не статьи по ES6. Конкретные претензии:

        Начиная от Java и заканчивая phonegap разработчики очень хотели, чтобы один раз написал и везде работало. Но не складывалось.

        А потом facebook сделал ReactJS. Чтобы чат себе починить. И сложилось.

        Но у React есть перед ними ряд преимуществ: web как одна из платформ, сверхпопулярный JavaScript, не менее популярный тулчейн node.js, бесплатность, поддержка facebook и “hot reloading” из коробки.

        В итоге статья с одним хайпом. Впрочем, пипл хавает, значит всем пофиг.
        • 0
          Да, мне нравится писать с хайпом. Если посмотреть на любые другие мои статьи, например вот этот цикл — я всегда так пишу. Менять стиль ради одного человека, которому он не нравится… Открою Вам большу тайну — всегда найдется тот, кому не нравится стиль статьи. Любой стиль. Академический — "слишком сухо", эмоциональный с упрощениями и безапелляционными высказываниями — "слишком много хайпа", точный — "ни о чем" и так далее. Жизнь — боль :)
          • 0
            А, извините, не увидел что вы евангелист. Все, вопросов нет.
    • +2
      У меня полностью противоположные впечатления — очень хорошо написано, редко такой уровень текста встречаю.
  • +1
    Дальше "hello world" эта штука не уедет, т.к. основная проблема не в интерфейсе, а в аппаратуре и принципах работы конкретных платформ.

    Для мобильного приложения нужно получать mcc, mnc, распознавать пользователя по imei, а при работе с файлами понимать, что приложение работает в виртуальной среде. Для десктопа нужно писать в реестр, параллельно по тихому устанавливать доп. софт и существенно расширять функционал работы с файлами. Для TV — работать с пультом и тщательно продумывать подсказки. Для веба — ещё 100500 своих требований. Разные среды — разный функционал, разные проблемы, решения, задачи и ТЗ.

    React Native не решает и в принципе не может решить ни одну из проблем, т.к. проблема в логике, а не инструментах.
    • 0
      P.S.: ну а в целом норм. статья
    • 0
      Для десктопа нужно писать в реестр

      Лучше не надо. Ну и МС ведет к тому, что это дело прикроет.
    • 0
      Вы правы, но не полностью, есть очень большой сектор программ, для бизнеса, когда половина функций мобильного не нужно, задача написать сложный в плане бизнес процесса продукт, выполняющий определенный функционал. Писать сложную бизнес логику на 3-4 системы, это ужас… А спецефичных штук чатсо не надо.
  • 0
    А в чём отличия от какой-нибудь кордовы с её WebView и набором platform-specific CSS'ов? Там тоже всё быстро писалось. Service (в понимании android) на reactnative всё так же не напишешь (без нативного кода). Если вы делаете серьёзное приложение, то вы либо "перейдёте на натив" (Java для андроида, ObjC/Swift для яблока), либо сделаете одно для всех. На С++ и opengl (см яндексовский навигатор например).
  • +1
    А почему не что-нибудь типа QML?
    • 0
      Выглядит чужеродно и на android и для ios, нет для веба.
      • 0
        В 5.6 они подготовили новую версию компонентов, специально для мобилок, там теперь есть даже Material стиль. Кроме того, саму систему стилей очень переработали, сделав её гораздо более удобной для изменения.

        А под Web действительно нет, но он там и не нужен, C++ всё таки.
        • 0
          Так если веб не нужен и, к примеру, андроид не нужен — то лучше всего нативно писать, swift все-таки. А если веб не нужен и ios не нужен — то лучше всего нативно писать, java все-таки :)
  • +1
    Кстати на react-native можно еще писать под osx и часы
    github.com/jondot/awesome-react-native#other-platforms
    • 0
      Увы, это пока игрушки от энтузиастов. Но лично я очень надеюсь на фейсбук ^_^
      • +1
        Это да. Но приятно, что osx версию делает российский разработчик из новосиба.
  • 0
    eyeofhell расскажите, пишите ли вы юнит тесты для ваших RN аппов и как именно?
    • 0
      Именно юнит тесты — пишем. Mocha + chai :)
      • 0
        1. А примеры посмотреть можно где-нибудь?
        2. Почему не jest?
        • 0
          Примеров пока нет, это во внутренних репозиториях. Возможно, в одной из следующих статей расскажу, мы как раз сейчас web sdk переписываем на typescript, можно будет показать как у нас все сделано. Почему не jest? Сам по себе test runner очень маленький относительно тестов, так что по большому счету все равно какой использовать. Мы используем самый популярный :). Если появится что-то, что в jest делается лучше и приносит пользуе — мы без проблем поменяем раннер, бо grep никто не отменял.
          • 0
            Ок, спасибо!
            Будет интересно почитать статью про тестирование RN.
  • +1
    А если мы захотим сделать версию для веба, то это займет от силы еще день (...). Все что нужно будет сделать – это заменить элементы пользовательского интерфейса на div’ы...

    Ох, не всё так просто.
    Таким образом вы получите:
    —дублирование копи-пейстом кодовой базы, которая не мержится автоматическими инструментами и придётся поддерживать в два раза больше кода
    —кучу инлайновых стилей
    —рендер всего приложения на клиенте, что сожрёт слабые машинки и будет крутить им прелоадер по несколько десятков секунд

    Да и вся вёрстка в react-native строится на flex, который пока ещё не частый гость в вебе
    • 0
      flex поддерживается уже всеми нормальными браузерами
    • 0
      • Дублировать ВСЕ не надо — достаточно имплементировать несколько компонент.
      • Если по каким-то причинам инлайновые стили не нравятся, то легким движением конфига вебпака они компилируются в отдельный css
      • Изоморфные приложения же! Все рендерится на сервере и мгновенно отдается CDN

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

Самое читаемое Разработка