NativeScript, что за зверь и для чего он нужен?

Доброго времени суток, хабражители, меня зовут Владимир Миленко, я frontend-инженер в компании Иннософт, географически расположенной в городе Иннополис и являющейся резидентом особой экономической зоны г. Иннополис.

Сегодня я поведаю о таком звере, как NativeScript(да, он изменился, да, сильно). NativeScript — фреймворк для кроссплатформенной разработки, придерживающийся концепции write once — use everywhere, и, возможно, у него получилось!


Что ты такое?


Начнем с простого, {N} это JS, который запускается на JSVM, специфичной для каждой системы(V8 для Android, WebKit iOS). И все-бы было бы грустно, если бы не одно но — NS предоставляет доступ ко всем системным API.

Т.е.

let card = new com.google.android.support.v7.widget.CardView(someContext);

— Валидный {N} код, который создаст proxy-объект, все обращения к которому будут вызывать нативные методы и возвращать результат от них.

Фактически, код выше показывает обращение к нативной подключаемой библиотеке для Android. В большинстве случаев такой длинный вызов вы напишете всего один раз при создании nativescript-плагина.

Execution flow в NativeScript выглядит следующим образом:


*Изображение взято с официальной документации NativeScript

В принципе, до момента релиза Angular 2, {N} имел весьма увесистые минусы, разметка описывалась с помощью xml, а весь функционал приходилось писать самому. Но при этом, {N} развивался и появились модули, позволяющие абстрагироваться от ОС, и использовать большинство стандартных фич, не заботясь о том, как конвертируются в нативные методы.

Например, следующий код будет выполнен нативными методами проверки существования файла.


import fs = require(“file-system”)
let exists = fs.File.exists(“abc.ini”); // будет вызван соответствующий нативный метод, после чего boolean из Java конвертируется в JS boolean.

В общем и целом, {N} — JS+XML, работающий на JSVM и позволяющий вызывать нативные методы из JS. При этом есть возможность использовать разметку ввиде XML и использовать некий сабсет CSS, а еще применять анимации и прочее.

Почему не ReactNative?



//здесь раньше было маленькое сравнение с React.Native, но ввиду моей ошибки я его убрал. Спасибо комментаторам.
Плюсы NativeScript:
Поддерживает все компоненты из AndroidArsenal и Cocoapods.
Поддерживает вызов нативных методов из нативных библиотек.
Минусы:
Эти вызовы придется декларировать, т.е. описать библиотеку(что в общем и целом не обязательно, достаточно описать лишь те методы, которые вы вызываете)

Главное преимущество — Angular 2 + NS


С выходом Angular 2 мир веба сотрясся, в т.ч. тряслись те, кто писал на rc версиях и изменял добрую половину кода под новый rc.

Команда проделала очень большуй работу и сделала Angular 2 максимально кастомизируемым. Хочешь переопределить рендер — пожалуйста, это-то и сделали ребята из Telerik.

Что же нам дает возможность писать приложения на Angular 2 + TypeScript + NativeScript? А дает это нам тот самый code-sharing, возможность использовать огромное количество фич ангуляра.

Теперь вы можете шарить ваши сервисы между веб-компонентом и между tns-компонентом.

Рассмотрим небольшой пример шаблона:



Здесь можно заметить директиву ngFor, что позволяет наиболее удобно выводить коллекцию, если же вам необходим ListView — там это делается с помощью шаблона, т.е. android разработчикам можно забыть про ViewHolder’ы и прочее.

А вот так этот код будет выглядеть на Android:



А вот так на iOS:



Также в разметке можно заметить platform-specific разметку, специфичную для каждой платформы:

<ios></ios>
<android></android

И раз уж заговорили о разметке, то нельзя не упомянуть two-way binding, который мы получаем с помощью angular 2:

Т.е. если описать переменную name в классе компонента, то чтобы привязать её к текстовому полю нужно написать вот такой код:

<TextField ([text])="variable"></TextField>

И к слову об анимации, вы можете описывать её с помощью css keyframes, использовать библиотеку keyfraymes или же оперировать через Promise.

Вот так выглядит анимация через Promise:


let view = this.page.getViewById("grid");
view
      .animate({backgroundColor: new Color("#efefef"), duration: 75})
      .then(
       () => {
                    view.animate({backgroundColor: new Color("white"), duration: 75});
        }
);

На этом небольшое интро подойдет к концу, опрос вы найдете чуть ниже.

Для того, чтобы понять, как Telerik смог использовать ангуляр рекомендую посмотреть выступление Алексея Охрименко с GDG Perm.

NativeScript

P.S. Разрабатывают NativeScript компания Telerik, которая является частью Progress. Это к слову о комментарие чуть ниже.

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

Стоит ли писать о {N} дальше?
Поделиться публикацией
Комментарии 54
    +2
    Первый раз слышу о таком, интересно. И приятно, что прям native-native.
    Хотелось бы увидеть статью: «Вот у нас мокап калькулятора» -> «Вот код» -> «Вот нюансы под iOs» -> «Тут мы берем и подключаем push'и да камеру» -> «магия» -> «Вот у нас готовые приложения под обе платформы»
      +1
      Калькулятор — это просто, пока что в планах на январские выходные — трекинг финансов.
      Состоять это дело будет из {N}+Angular+ngrx/store+Firebase.
        0
        Я тоже в своё время заинтересовался Angular 2 + Ionic 2 (конкурент NativeScript и в каком то роде аналог) и за 2 недели сделал приложение для учёта долгов. И уже второй код допиливаю до состояния продукта — альфа/бета, интеграция с соцсетями, боты для Телеграм и Вайбера и т.п.

        Что нравится в подходе Ionic и NativeScript что можно тот-же код для web-приложения использовать.

        Я например прямо на сайте выкладываю live-demo чтобы сразу понятно было как будет выглядеть и работать приложение на мобиле — DebtsTracker.io
          0
          Ionic это все-же о другом, там используется WebView, здесь же native.
          При этом код так же можно переиспользовать в вебе.
            0

            Я понимаю, потому и написал что "как бы" аналог. Но однозначно конкурент для определенных ситуаций. Когда нужен только натив то NativeScript конечно выигрывает.

      +2
      Скажите, а если закончатся бюджетные деньги и у вас все гикнется, что будут делать бедные разработчики со своей кодовой базой под стремительно стареющий фреймворк, который больше не поддерживается?
        0
        Какой фреймворк не поддерживается? Angular 2 в самом расцвете, nativescript точно так же.
        И какие бюджетные деньги?:)
          +1
          Вот знаете, абсолютно нет ощущения, что NativeScript в самом расцвете, скорее на стадии отчаянной альфы. Рассматривали тут месяца два назад — проблемы с документацией (точнее примерами на гитхабе — не все даже компилируется/работает, а Telerik и не в курсе). Проблемы с количеством существующих компонентов (ну вот карт, например, не было). Можно да, написать свою собственную обертку. И над iOS, и над Android. Ужасным синтаксисом. Только вот не вижу тут тогда никакой выгоды.
          Как результат, сделали вывод — Todo-list приложения писать можно :) А еще, как еще один результат, пришлось чуть-чуть пожить с ужасающим аддоном к VS и кучей спама от Телерика.
            –1
            Если для вас синтаксис TS ужасен — я даже не знаю, что предложить:)
            По поводу не компилируется — тестил различные модули и продолжаю с ними работать, стоило создать issue, вам бы помогли.
            Ужасающий аддон? Для VS Code и WebStorm есть достаточно хорошие плагины.
              +1
              синтаксис TS то не ужасен, это просто я криво выразился :) Ужасно различное количество доп. плясок вокруг всего этого для создания врапперов — http://docs.nativescript.org/plugins/ui-plugin

              Все проблемы с документацией (вот код по линку в предыдущем абзаце — не работал) были пофиксены где-то в ноябре, спустя месяц как мы на него пожаловались. Нет, ну можно сказать что помогли :) Я не говорю, что этим невозможно пользоваться — я говорю о том, что при выборе стратегии мобильного девелопмента на длительное время вперед, это не то, что я лично готов выбрать или кому-то порекомендовать.

              PS: Под ужасающим я имел в виду примерно ту кучу спама (в виде попапов, доп. окошек, доп. таргетов output'ов, которые почему-то на каждый перезапуск по дефолту выбираются и т.д.), которую он везде прокидывал.
              +2
              Еще добавлю к sAntee. Лучше держитесь по дальше от Telerik, мы работали с продуктами этой компании и от них у нас были одни проблемы + ужаснейший саппорт.
          0
          Лично мне больше интересно, можно ли как-то разрабатывать кроссплатформенно, находясь в винде/линуксе. Теоретически я понимаю, что можно поднять виртуальную машину с макосью, и на ней билдить через консольные xcode tools.
          Практически — не представляю как всё это вообще поднять, и какую IDE для разработки использовать.
            +2
            Под виндой можно легко разрабатывать под андроид, ios — тут уж извините, можно арендовать сервер и пробрасывать билд через него.
            Из IDE-лично рекомендую WebStorm.
              0
              Любую IDE для javascript
                +1
                Можно использовать PhoneGap. В облаке у них приложения собирать для iOS. Как вариант.
                  0
                  А как насчёт установить макось в виртуалке? У меня коллега так делает, работая на винде.
                  0
                  ReactNative ограничивает вас в компонентах

                  Не понимаю, это как?
                    0
                    Не так выразился.
                    Чтобы использовать CocoaPods/AA в react-native вам придется писать соответствующие классы на objC/Java.
                    Создавать, так скажем, мост между ними.
                    Однако вызывать нативные библиотеки, не JS — у вас не получится из JS'а.
                      0
                      Спасибо.

                      По этому преимущества {N} не совсем очевидны (если они конечно есть).
                        0
                        Вызов функций нативных библиотек из JS — это серьёзное преимущество.
                        0
                        На сколько я знаю в React Native, там тоже можно подключать через NativeModule (тот же самый мост), преимущества по сравнению с NativeScript не вижу. Если есть подробнее, можете изъяснить в чем же отличие то что описали выше?
                          +2
                          Мосты в ReactNative пишутся на objC/Java, и представляют собой врапперы, по сути.
                          В nativescript ваш вызов просто конвертируется в нативный без написания врапперов.
                          Написние декларации не обязательно, оно просто помогает в дальнейшем понять, что происходит без документации.
                      0

                      Я правильно понял, что в основе — что-то вроде js-ctypes? Или получилось удобнее? (использование js-ctypes всё-таки включает в себя кучу возни и великолепные возможности для выстрела себе в ногу)

                        0
                        Выстрелить себе в ногу вам не даст execution flow.
                        Для начала, вам не дает выстрелить себе в ногу TypeScript(по понятным причинам, compile-time type-checking).
                        Затем во время уже исполнения, вам будет мешать TypeConversion, если что-то пойдет не так — вам укажут где и почему.
                        Но опять-таки, возвращаясь к теме TS — его не просто так выбрали для Ангуляра, он действительно не дает вам возможности пострелять вдоволь.

                        Вообще, Telerik предоставляет декларацию типов для всех нативных вызовов. Для тех модулей, которые вы пишите сами — вы так же можете описать декларацию, заранее уберегая себя и дальнейших разработчиков от проблем с типизацией.
                        0
                        В чем приемущество перед ReacNative совершенно не ясно. За ReactNative стоит FB и его используют уже AirBnb и другие гиганты и у меня нет сомнений в его будущем. Будущее же Native Script очень сомнительно. Я в своей компании, пытаюсь организовать переход с нативной разработки на ReactNative, так как это позволит нам больше и быстрее проводить эксперименты и a/b тестирования без обновления приложения в сторе. Если у вас этой культуры нет и не предвидится, то я бы трижды подумал, почему не писать нативный код для каждой платформы.
                          +2
                          Вы планируете использовать CodePush, который точно так же будет введен и для NativeScript.
                          NativeScript развивается Telerik и только начинает свой путь в связке c Angular.
                          Возможно, когда-нибудь он станет AngularNative;)
                          Команда Angular тесно сотрудничает с Telerik, Microsoft тесно сотрудничает с Angular.
                          Все просто:)

                          Выбирая же путь ReactNative — вы выбираете путь react, NativeScript — angular.

                          Все зависит от того, с чем уже работала ваша команда, если у вас есть опыт с Angular2 — выбор очевиден.
                            0

                            Меня больше интересует возможность использования {N} без ангуляра. Насколько его полноценно можно использовать?

                              0
                              Точно так-же, как и с Ангуляром.
                              {N} не обязывает вас использовать Angular.
                              Просто разметка превращается в полный xml, убираются все плюшки ангуляра, убирается также возможность использовать написанные «сервисы» в вебе
                                0

                                А без xml нельзя?

                          +3

                          "ReactNative использует DOM..."


                          Вы в этом уверены? Хотя бы в документацию посмотрели. Вот неплохая презентация https://speakerdeck.com/mkonicek/under-the-hood-of-react-native

                            –3
                            Поправлю, VirtualDOM.
                            Суть меняется, но не столь критично. При изменении состояния компонента все-равно идет проверка, нужно ли его ререндерить.
                              0

                              Вообще-то суть меняется радикально.


                              В Ангуляре тоже есть проверка, только немного другая. Упрощенно можно сказать, что в Ангуляре сравниваются данные, в Реакте — сравнивается виртуальный DOM (однако можно вмешаться и сделать проверку данных).

                                0
                                А виртуал дом в свою очередь тоже просто данные по сути) итого сравнения одинаковые)
                                  0

                                  формирование этих даннгх обходится не бесплатно.

                            +3

                            С чего вы решили, что в ReactNative используется DOM?

                              0
                              Поправил в статье, ошибка. В одной из презентаций от Telerik, они упомянули DOM, но не упомянули virtual.
                              В прочем, к статье RN не имеет никакого отношения и стоило его убрать.
                              Спасибо.
                                0

                                В итоге почему не ReactNative?

                                  0
                                  Я выше написал, если важно иметь удобный доступ когда всем системным апи и при нежелании писать на objC/Java — NS. Если команда работает с Ангуляром-тоже логично.
                                  Команда работает с react'ом — реакт.
                                  В некоторых моментах реакт будет быстрее, в некоторых медленнее
                              0
                              Очень интересная статья. Буду ждать продолжения.
                              Хочется увидеть полный цикл разработки от настройки IDE до компиляции.
                              Идея хорошая и возможности интересные.
                                +4

                                Я правильно понимаю, что получился прямой аналог Xamarin.Forms (даже разметка с местным XAML схожа до степени смешения), только на яваскрипте и ещё более тормозной?

                                  –2
                                  Производительность у nativescript проигрывает только при запуске приложений, маршаллинге примитивов.(информация годичной давности, {n} был версии 1.3-1.4, сейчас 2.4.
                                  Однако при этом, сам fps стабильно выдает 60 кадров, при маршаллинге комплексных переменных NS проигрывает только нативному коду.
                                  История с запуском лечится lazy-loading'ом.
                                  Конкретно сейчас по цифрам сказать можно одно, где-то NS будет быстрее, где-то медленнее, но на UX это не скажется никак.

                                  С XAML'ом похоже засчет того, что оба были построены на xml.
                                  Вот только XAML вышел слегка ущербным, а здесь при дополнении ангуляром мы получается очень удобный и мощный инструмент для создания шаблонов

                                    +2

                                    Ну коли полезли в лес, покажите, на основе чего вы решили, что разметка ангуляра менее ущербна, чем xaml. А то, судя по статье и комментам, выглядит, что, скрываясь за крайне интересным NS, вы пытаетесь продать ng2. Не надо так

                                      –2
                                      Ng2 продают другие, а по поводу сравнения xaml с ng2 — Все очень просто, разметка в ангуляре удобнее за счет его директив, т.е. это и циклы в разметке, и условия, ngIf,ngFor(в xaml'е отсутствует)
                                      Conditional's в xaml'е устанавливаются через триггеры(что увеличивает лэйаут на N строк.
                                      Согласитесь, куда более удобно написать:
                                      [class.active]=«isActive», чем писать в через триггеры и сеттеры.

                                      А по поводу крайне интересного NS — все верно, он интересен, но в связке с ng2 он становится в разы интереснее, тут вам и встроенный DI, и шаблоны, и структурные директивы.
                                      Никто не запрещает писать на чистом NS, но гораздо удобнее все-таки в связке с ng2.
                                        +3

                                        Интересно, что же вам мешает использовать свои компоненты в xaml?
                                        А для ngFor есть байндинг на списки, для ngIf — байндинг на проперти, безо всякой кастомной синтаксической дури. Мне например не очень по душе упаковка логики в dsl только ради упаковки этой логики в шаблон.

                                  0
                                  С точки зрения мобильной разработки мне всегда интересно, а сколько рантайма такие приложения будут тащить с собой? Во времена прошлые оно тащило 12+ мегабайт V8 в дополнение к другим ресурсам, которые вместе с запущенным приложением занимают место в оперативке. А как сейчас?
                                    0
                                    Ничего не изменилось, все улучшения были сделаны в пользу уменьшения нагрузки на cpu/gpu.
                                      +1
                                      Извините за дилетантский вопрос — а насколько это важно/критично? Можно где то об этом почитать?

                                      А то вот не могу понять нужно ли включать в моё приложение на Ionic Crosswalk или нет.
                                        –2
                                        Самое очевидное вот, статья старая, но принцип думаю сильно не поменялся. Менее очевидное касается странных конфигураций андроидофонов, на которых весьма немного памяти, и +12мб там — много.
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                          +1
                                          Для андроида сейчас пока что тащит тоже, разве что можно исключить ненужные ABI (x86, arm64-v8a, armeabi-v7a) путем ручного выпила по соответствующему пути и указанию в конфиге. Каждая ABI весит как раз чуть больше 4 Мб.
                                          +1
                                          а что с производительностью? смотрел демки от Телерик на андроид устройстве — оно реально подтормаживало, там где Cordova не сказать бы что летал, но работал хорошо. А тут еще ng2 добавили…
                                            0
                                            Кордова это опять-таки о другом, демки NS у меня подтормаживали только при большом количестве анимации.
                                            В appstore/gplay есть NativeScript demo.

                                            Как я уже упоминал раньше, фпс стабильно держится на уровне 60 кадров
                                            0

                                            Вызов нативного апи одновременно заманивает и настораживает. Действительно любое нативное апи можно вызывать со всей спецификой из NS или только для которого позаботились написать интерфейс? К Objective-C и Java можно гарантировано не обращаться по задачам оптимизации, реализации js api к сторонним нативным компонентам? Можно пример работы с 2D графикой (нарисовать полигон)?

                                              0
                                              Действительно любое, если вдруг какого-то нативного метода нет в декларации, достаточно просто его описать(тип возвращаемого значения и параметры)
                                              Работа с 2д — специфична для каждой платформы, есть плагины, которые уже реализуют подобное, достаточно их подключить, описав common функции и специфичные для каждой платформы(думаю, здесь понятно, один плагин будет иметь свою спецификацию для андроида, второй будет из cocoapods).
                                              Чуть позже приведу пример

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

                                            Самое читаемое