Доброго времени суток, хабражители, меня зовут Владимир Миленко, я 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} дальше?

Проголосовало 540 человек. Воздержалось 190 человек.

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

Поделиться с друзьями
-->

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


  1. Carduelis
    03.01.2017 20:42
    +2

    Первый раз слышу о таком, интересно. И приятно, что прям native-native.
    Хотелось бы увидеть статью: «Вот у нас мокап калькулятора» -> «Вот код» -> «Вот нюансы под iOs» -> «Тут мы берем и подключаем push'и да камеру» -> «магия» -> «Вот у нас готовые приложения под обе платформы»


    1. AsTex
      03.01.2017 20:45
      +1

      Калькулятор — это просто, пока что в планах на январские выходные — трекинг финансов.
      Состоять это дело будет из {N}+Angular+ngrx/store+Firebase.


      1. astec
        04.01.2017 16:16

        Я тоже в своё время заинтересовался Angular 2 + Ionic 2 (конкурент NativeScript и в каком то роде аналог) и за 2 недели сделал приложение для учёта долгов. И уже второй код допиливаю до состояния продукта — альфа/бета, интеграция с соцсетями, боты для Телеграм и Вайбера и т.п.

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

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


        1. AsTex
          04.01.2017 16:26

          Ionic это все-же о другом, там используется WebView, здесь же native.
          При этом код так же можно переиспользовать в вебе.


          1. astec
            04.01.2017 16:29

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


  1. dmitryredkin
    03.01.2017 21:05
    +2

    Скажите, а если закончатся бюджетные деньги и у вас все гикнется, что будут делать бедные разработчики со своей кодовой базой под стремительно стареющий фреймворк, который больше не поддерживается?


    1. AsTex
      03.01.2017 21:07

      Какой фреймворк не поддерживается? Angular 2 в самом расцвете, nativescript точно так же.
      И какие бюджетные деньги?:)


      1. sAntee
        04.01.2017 18:21
        +1

        Вот знаете, абсолютно нет ощущения, что NativeScript в самом расцвете, скорее на стадии отчаянной альфы. Рассматривали тут месяца два назад — проблемы с документацией (точнее примерами на гитхабе — не все даже компилируется/работает, а Telerik и не в курсе). Проблемы с количеством существующих компонентов (ну вот карт, например, не было). Можно да, написать свою собственную обертку. И над iOS, и над Android. Ужасным синтаксисом. Только вот не вижу тут тогда никакой выгоды.
        Как результат, сделали вывод — Todo-list приложения писать можно :) А еще, как еще один результат, пришлось чуть-чуть пожить с ужасающим аддоном к VS и кучей спама от Телерика.


        1. AsTex
          04.01.2017 18:25
          -1

          Если для вас синтаксис TS ужасен — я даже не знаю, что предложить:)
          По поводу не компилируется — тестил различные модули и продолжаю с ними работать, стоило создать issue, вам бы помогли.
          Ужасающий аддон? Для VS Code и WebStorm есть достаточно хорошие плагины.


          1. sAntee
            04.01.2017 19:08
            +1

            синтаксис TS то не ужасен, это просто я криво выразился :) Ужасно различное количество доп. плясок вокруг всего этого для создания врапперов — http://docs.nativescript.org/plugins/ui-plugin

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

            PS: Под ужасающим я имел в виду примерно ту кучу спама (в виде попапов, доп. окошек, доп. таргетов output'ов, которые почему-то на каждый перезапуск по дефолту выбираются и т.д.), которую он везде прокидывал.


        1. cyber_ua
          05.01.2017 12:19
          +2

          Еще добавлю к sAntee. Лучше держитесь по дальше от Telerik, мы работали с продуктами этой компании и от них у нас были одни проблемы + ужаснейший саппорт.


  1. Starche
    03.01.2017 21:08

    Лично мне больше интересно, можно ли как-то разрабатывать кроссплатформенно, находясь в винде/линуксе. Теоретически я понимаю, что можно поднять виртуальную машину с макосью, и на ней билдить через консольные xcode tools.
    Практически — не представляю как всё это вообще поднять, и какую IDE для разработки использовать.


    1. AsTex
      03.01.2017 21:10
      +2

      Под виндой можно легко разрабатывать под андроид, ios — тут уж извините, можно арендовать сервер и пробрасывать билд через него.
      Из IDE-лично рекомендую WebStorm.


    1. span4ik
      03.01.2017 21:11

      Любую IDE для javascript


    1. ZoomLS
      03.01.2017 21:15
      +1

      Можно использовать PhoneGap. В облаке у них приложения собирать для iOS. Как вариант.


    1. zikolach
      04.01.2017 11:13

      А как насчёт установить макось в виртуалке? У меня коллега так делает, работая на винде.


  1. hose314
    03.01.2017 22:00

    ReactNative ограничивает вас в компонентах

    Не понимаю, это как?


    1. AsTex
      03.01.2017 22:05

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


      1. hose314
        03.01.2017 22:19

        Спасибо.

        По этому преимущества {N} не совсем очевидны (если они конечно есть).


        1. Zibx
          04.01.2017 01:46

          Вызов функций нативных библиотек из JS — это серьёзное преимущество.


      1. zhanbst
        04.01.2017 16:30

        На сколько я знаю в React Native, там тоже можно подключать через NativeModule (тот же самый мост), преимущества по сравнению с NativeScript не вижу. Если есть подробнее, можете изъяснить в чем же отличие то что описали выше?


        1. AsTex
          04.01.2017 16:32
          +2

          Мосты в ReactNative пишутся на objC/Java, и представляют собой врапперы, по сути.
          В nativescript ваш вызов просто конвертируется в нативный без написания врапперов.
          Написние декларации не обязательно, оно просто помогает в дальнейшем понять, что происходит без документации.


  1. aamonster
    04.01.2017 00:41

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


    1. AsTex
      04.01.2017 00:51

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

      Вообще, Telerik предоставляет декларацию типов для всех нативных вызовов. Для тех модулей, которые вы пишите сами — вы так же можете описать декларацию, заранее уберегая себя и дальнейших разработчиков от проблем с типизацией.


  1. asivura
    04.01.2017 00:51

    В чем приемущество перед ReacNative совершенно не ясно. За ReactNative стоит FB и его используют уже AirBnb и другие гиганты и у меня нет сомнений в его будущем. Будущее же Native Script очень сомнительно. Я в своей компании, пытаюсь организовать переход с нативной разработки на ReactNative, так как это позволит нам больше и быстрее проводить эксперименты и a/b тестирования без обновления приложения в сторе. Если у вас этой культуры нет и не предвидится, то я бы трижды подумал, почему не писать нативный код для каждой платформы.


    1. AsTex
      04.01.2017 00:59
      +2

      Вы планируете использовать CodePush, который точно так же будет введен и для NativeScript.
      NativeScript развивается Telerik и только начинает свой путь в связке c Angular.
      Возможно, когда-нибудь он станет AngularNative;)
      Команда Angular тесно сотрудничает с Telerik, Microsoft тесно сотрудничает с Angular.
      Все просто:)

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

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


      1. vintage
        04.01.2017 02:06

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


        1. AsTex
          04.01.2017 02:13

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


          1. vintage
            04.01.2017 11:04

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


  1. webschik
    04.01.2017 01:30
    +3

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


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


    1. AsTex
      04.01.2017 01:35
      -3

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


      1. indestructable
        04.01.2017 02:05

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


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


        1. gibson_dev
          04.01.2017 07:42

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


          1. vintage
            04.01.2017 11:05

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


  1. boolive
    04.01.2017 01:30
    +3

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


    1. AsTex
      04.01.2017 03:55

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


      1. boolive
        04.01.2017 18:54

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


        1. AsTex
          04.01.2017 19:15

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


  1. sidny_vicious
    04.01.2017 03:02

    Очень интересная статья. Буду ждать продолжения.
    Хочется увидеть полный цикл разработки от настройки IDE до компиляции.
    Идея хорошая и возможности интересные.


  1. kekekeks
    04.01.2017 06:00
    +4

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


    1. AsTex
      04.01.2017 06:26
      -2

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

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


      1. raveclassic
        04.01.2017 15:26
        +2

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


        1. AsTex
          04.01.2017 15:44
          -2

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

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


          1. raveclassic
            04.01.2017 16:00
            +3

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


  1. SBKarr
    04.01.2017 11:44

    С точки зрения мобильной разработки мне всегда интересно, а сколько рантайма такие приложения будут тащить с собой? Во времена прошлые оно тащило 12+ мегабайт V8 в дополнение к другим ресурсам, которые вместе с запущенным приложением занимают место в оперативке. А как сейчас?


    1. AsTex
      04.01.2017 14:30

      Ничего не изменилось, все улучшения были сделаны в пользу уменьшения нагрузки на cpu/gpu.


    1. astec
      04.01.2017 16:19
      +1

      Извините за дилетантский вопрос — а насколько это важно/критично? Можно где то об этом почитать?

      А то вот не могу понять нужно ли включать в моё приложение на Ionic Crosswalk или нет.


      1. SBKarr
        04.01.2017 16:57
        -2

        Самое очевидное вот, статья старая, но принцип думаю сильно не поменялся. Менее очевидное касается странных конфигураций андроидофонов, на которых весьма немного памяти, и +12мб там — много.


      1. raidhon
        04.01.2017 23:32
        +1

        Без Crosswalk боюсь ваше приложение не будет нормально работать на всех поддерживаемых ionic устройствах.


    1. p0rsche
      04.01.2017 17:02
      +1

      Для андроида сейчас пока что тащит тоже, разве что можно исключить ненужные ABI (x86, arm64-v8a, armeabi-v7a) путем ручного выпила по соответствующему пути и указанию в конфиге. Каждая ABI весит как раз чуть больше 4 Мб.


  1. adasoft
    04.01.2017 16:27
    +1

    а что с производительностью? смотрел демки от Телерик на андроид устройстве — оно реально подтормаживало, там где Cordova не сказать бы что летал, но работал хорошо. А тут еще ng2 добавили…


    1. AsTex
      04.01.2017 16:29

      Кордова это опять-таки о другом, демки NS у меня подтормаживали только при большом количестве анимации.
      В appstore/gplay есть NativeScript demo.

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


  1. boolive
    04.01.2017 16:34

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


    1. AsTex
      04.01.2017 16:44

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