Neutralinojs — что ты такое? Или UNIX way там, где не ждали

    Недавно я совершенно случайно наткнулся на простую рекламную заметочку "Neutralinojs — альтернатива Electron, потребляющая меньше памяти", рассказывающую о том, что есть такая крутая вещь как Neutralinojs. Заметочка, как и следует ей быть, совсем короткая и не несёт никакой полезной информации, кроме рекламного лозунга "Лучше чем <что-то популярное>!"


    Примерно понимая как работает Electron и NW.js и не найдя совершенно никакого упоминания о принципе работы этого нового и суперкрутого "чудо-зверя" в заметке, я начал исследования.


    Собственно представляю вниманию результаты своего микро-исследования!



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


    • Почему оно ест в разы меньше памяти?
    • Какие даёт ещё плюшки?
    • Для чего мне это чудо использовать?

    Почему не жрём память?


    Покопавшись в исходниках и двух достаточно информативных картинках об архитектуре, я понял, что этот проект работает именно по тому самому UNIX Way, который любят все линуксоиды. Философия проекта проста: зачем придумывать новый велосипед, если можно использовать уже готовый?


    В чём минусы Electron:


    • Тащим с собой Chrome
    • Тащим с собой Node.js
    • Тащим с собой прослойку, чтобы два предыдущих работали вместе

    Вместо этого всего сделано так:


    • Мы не тащим Chrome
    • Мы не тащим Node.js
    • Мы тащим только прослойку между каким-то браузером и какой-то ОС

    Давайте посмотрим как конкретно это реализовано.


    Архитектура



    Весь проект состоит из 2 частей: сервера и клиента.


    Сервер запускается сразу и является настоящим партизаном в тылу ОС. Он умеет хранить данные, открывать файлы, писать в файлы, запускать крипторы shell-команды. Собственно он делает всё, что может понадобиться, предоставляет API для операционки и общается с помощью HTTP с клиентом. Так же он отдаёт клиенту всё, что тот должен отобразить на экране. Достаточно стандартная функциональность для сервера.


    Для каждой операционной системы был форкнут и доработан напильником свой сервер на C++. Под Mac пока не нашли что форкнуть, поэтому и поддержки нет.


    Клиентов может быть 3 типа:


    • cloud — Любая программа, знающая порт, на котором работает сервер, может исполнять команды
    • browser — Сервер сам запускает процесс стандартного системного браузера с нужным URL. Тут сервер требует уже специальный TOKEN, который сам вставляет в отдаваемые HTML странички.
    • window — Сервер запускает специальный render процесс, который просто отображает системный WebView. Тут тоже нужен токен

    Тут нужно отметить, что сервер может работать одновременно только с одним типом клиента, и указать тип клиента нужно в конфиге с помощью поля mode.


    Как видите, ничего лишнего. Само по себе приложение на этом "фреймворке" состоит из исходников, которые получаются клиентом как статика, и собственно сервера, который умеет натравливать либо браузер, либо WebView на необходимый URL. Вот что значит истинный DRY!


    Какие плюшки?


    Из плюшек, конечно же, меньшее потребление памяти. Так как не несётся с собой ни Node.js, ни Chrome, доставляемые клиенту данные очень малы в объёме. Так же разработчики настаивают, что не нужно качать какие-то непонятные builder'ы, не нужно тратить время на компиляцию и всё такое.


    Собственно из плюсов это всё, теперь перейдём к минусам.


    Сразу хочу оговориться, что проект очень молодой, живёт чуть более 5 месяцев, но он уже гордо носит версию 1.1.0, так что считаю, что имею право оценивать продукт как уже готовый, и предъявлять ему требования такие же, как и к конкурентам.

    Болячки NW.js


    Тут у нас сразу веер проблем, которые мягко перекочевали из NW.js.


    Первое, и самое заметное для пользователя — поставка приложения. Чтобы клиент запустил у себя на компе нашу программку, ему нужно иметь 2 главные вещи: neutralino.exe и папку app/. Внутри папки хранятся все настройки (вроде режима работы сервера и заголовка окна) и собственно index.html, который отдаётся клиенту. Самый простой способ — это дать пользователю zip-архив и сказать на какую програмку тыкать, но пользователи всё равно найдут, что сделать не так, как в инструкции и что сломать.


    Для решения этой проблемы в NW был создан builder, который умел упаковывать всё в exe, вместе с ICO и архивами. Менее очевидным решением были SFX архивы, но на них в принципе косо смотрят антивирусы, так что тоже не очень хороший вариант. Сами разработчики планируют всё же сделать свой packer, но пока о нём только слухи ходят.


    Вторая проблема заключается в точке входа. Это всегда index.html. Вы не можете ничего с этим сделать и даже указать другой файл. Все скрипты, которые нужны приложению, должны быть загружены в этом index.html. Проблема не сильно большая, но гибкость системы это уменьшает в разы.


    Какой-то браузер


    Тут всё ещё хуже, чем у NW.js или Electron. Если в последних мы точно знаем версию браузера, который будет отображать наше приложение, то тут мы в принципе не можем быть уверены, что ОС предоставит нам WebView, умеющий работать с JS. То есть мы возвращаемся в лихие нулевые и ухищряемся всеми возможными способами, чтобы попасть в тот самый IE 8, который будет стандартным WebView на Windows.


    Это ограничивает наше приложение в части отображения и проигрывания каких-нибудь медиа файлов, а это основная функция приложений, разработанных по принципу "Web for Desktop".


    API


    Поскольку авторы стремятся к минимализму, то предоставляемый сервером API не отличается разнообразием методов. Я бы даже сказал не отличается продуманностью. Всё это небуйство описано в такой же скудной документации.


    Единственный, кто умеет общаться с системой — Neutralino сервер, то мы должны как-то общаться с ним. Канал связи односторонний — HTTP. По сути все, что нам дают использовать в JS — просто wrapper вокруг REST API сервера.


    Весь API можно поделить на 3 части: работа со Storage, сильно базовая работа с FS (только читать, удалять и создавать — никаких излишеств) и вызов системных окон и команд.


    А теперь пробежимся по самому дизайну API, доступному из JS.


    Начнём с callback'ов. Так как браузер у нас какой-то, то и ES5, а соответственно и Promise, использовать не получится. А так как Node.js разработчики на дух не переносят, то и Node-like колбеки использовать они не хотят. Поэтому у каждого метода есть 2 колбека: один для результата, а другой для обработки ошибок, формат которых, кстати, не известен.


    На счёт результатов: у большинства команд, например, работающих с OS, в колбек передаётся объект с полем stdout, внутри которого находится строка. Как вы уже поняли, читать файлы большого объёма и тем более обрабатывать их в каком-нибудь Buffer-like объекте не получится. У системных окон результат в другом формате, там используется объект с полем file. Вопрос "почему же в принципе нужны объекты с одним полем" остаётся не отвеченным.


    А теперь перейдём к Storage. В нём есть такие сущности как bucket'ы, которые сохраняются как JSON-файлы рядом с исходниками приложения. При этом, чтобы записать данные в какой-то bucket, мы должны передать объект, с именем bucket'а и его новым содержимым. Чтобы получить данные, передаём только строку — имя bucket'а. Никакого намёка на схожесть со стандартным Storage интерфейсом, зачем, делаем свой велосипед...


    Ну и давайте немного про интеграцию с ОС. Вспомним, что Electron и даже NW предлагали возможность создания своих Context Menu, разрешали скрывать окно и даже создавать иконку в трее. Тут этого всего просто нет. И, учитывая архитектуру решения, никогда не будет. Только браузер и только REST API, только хардкор.


    Для чего можно использовать?


    Я долгое время считал, что если нужно просто перенести форму регистрации из сайта в десктопное приложение, то можно использовать NW.js и не париться. Если нужно что-то посложнее, что-то, что требует интеграции с системой в графическом плане, то это Electron. Да, у каждого свои минусы, но это уже хоть какие-то продукты, на которых можно делать своё приложение.


    Но Netralinojs тоже можно использовать. Например, какой-нибудь чатик будет работать достаточно неплохо, только на сервере надо будет настроить CORS. Какой-нибудь маленький графический генератор текстовых конфигов будет вполне себе хорош. Для себя я вижу этот фреймворк только как платформу для маленьких утилит с графическим интерфейсом, которые нужно будет запускать не часто и не на долго. Думаю вы тоже можете вспомнить из своей профессиональной деятельности хотя бы один маленький продукт, который бы мог работать на столь минималистичной платформе.


    Вывод


    Фреймворк на самом деле очень и очень сырой. Его минимализм может быть его сильной стороной, но как только потребуются фичи, которые выходят за рамки API, то придётся переходить либо на Electron, либо на NW.js.


    Я очень надеюсь, что v1.1.0 — не последняя, и что разработчики ещё переделают многие огрехи в дизайне своего API и предоставят более гибкие возможности по настройке и поведению приложения. Так же надеюсь, что они всё же найдут статический сервер на плюсах, который можно было бы форкнуть и использовать на Mac.


    Ну и ссылочки, чтобы было более понятно:



    UPD:


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

    Будете ли пробовать?

    • 23,8%Да, интересно посмотреть на новое видиние34
    • 18,2%Да, но кажется оно не взлетит26
    • 41,3%Не, зачем силы тратить на ещё одну поделку59
    • 16,8%Меня устраивает Electron24

    Чем уже пользовались?

    • 89,1%Electron82
    • 37,0%NW.js34

    NW.js мёрт?

    • 21,4%Скорее жив, чем мертв21
    • 60,2%Скорее мёртв, чем жив59
    • 18,4%Мертвее не бывает18

    Комментарии 17

      +2
      Предлагаю КДПВ:
      Спойлер
      image

        +7
        > Мы тащим только прослойку между каким-то браузером и какой-то ОС

        Мне кажется одна лишь эта фраза сразу говорит нам, что подводных камней там полно.
          0
          Да уж, если «какой-то браузер» ещё не очень пугает (м.б. зря), то «какая-то ОС» — совсем беда. По-хорошему, нужно сделать единообразную прослойку ко всем функциям каждой ОС.

          Так себе и представил ситуацию: ваяем на Нейтралино систему, вгрохали десяток человеколет, остаётся маленький штрих, без которого Заказчик не принимает — чтобы эта штука задействовала КриптоПро через виндовозный CryptoAPI. Плюс позарез оказалось нужно взаимодействовать с железячкой, для которой есть DLLка.

          Впрочем, если сделают возможность приделывать к серверу написанные на плюсах плагины, то можно будет и выкрутиться.
            0
            > если сделают возможность приделывать к серверу написанные на плюсах плагины, то можно будет и выкрутиться.

            Проблема в том, что под каждую ОС свой сервер. А если вы делаете под одну ОС, то возникает вопрос почему не делаете нативно, раз умеете писать на плюсах плагины)
              0
              Предположим, затея взлетела, и писать кроссплатформенные штуки на этой штуке оказалось фантастически удобно. Сваяли большую красивую штуку, и тут это гадское КриптоПро. Делаем по-быстрому шлюз на CryptoAPI, и для Виндовса кнопка подписания электронной подписью появляется. А на других платформах она, допустим, и не нужна.
              В общем объёме кодовой базы проекта этот шлюз порядка одного процента.
              А нативно на плюсах, допустим, этот проект тоже можно было бы делать, но за на порядок больший бюджет, которого у Заказчика точно нет.
              0
              Впрочем, если сделают возможность приделывать к серверу написанные на плюсах плагины, то можно будет и выкрутиться.

              может проще будет использовать Chromium Embedded Framework?
          • НЛО прилетело и опубликовало эту надпись здесь
              0
              т.е. node.js работает на удалённом сервере и всё крутится на нём, используется его файловая система, память и т.п., а ты только через браузер смотришь на результат.

              Веб называется. Нет ну серьезно, а зачем? То что вы описали по сути обычное веб-приложение.
              На счёт сетевых задержек, есть такой сервис playkey, он позволяет играть в игры на облаке, я так понимаю, передавая в браузер видео достаточно хорошего качества и принимая события с устройств ввода и вроде ок. Так же на хабре была статья как пробросить иксы в браузер(Вот тут не скажу на сколько оно лагучее).
              • НЛО прилетело и опубликовало эту надпись здесь
              0
              Годная штука. Меня (как пользователя слаки) электрон отталкивает именно что своей жуткой неюниксвейностью. Очень надеюсь, что и во всякой убунте на правах пакета эта штука тоже приживётся со временем (и несколько тяжеловесное название этому не помешает).

              Отсутствие прибитости к хрому тоже скорее в плюс, чем в минус, я может быть старомоден, но написание больших десктопных приложений привязанных к особенностям одного, пусть и самого распространённого броузера по мне — некомильфо. Как то напоминает времена виндовых приложений с использованием MSHTML engine (хотя опенсорсный fb2editor в wine таки запустить можно).

              А так — если уж используешь фронтэндерскую технологию — будь добр писать мало-мальски кроссброузерный код, чтобы это можно и в веб выложить, без баннера «сайт доступен только для IE6 Chrome».

              Ладно, Atom и VSCode — это уже «реальность данная нам в ощущениях» (хотя я предпочитаю Sublime и, в качестве открытого аналога, TextAdept, полностью переконфигурируемый на lua). Но основное применение js-на-десктопе, как мне представляется, всё же должно быть иным.
                +1

                Больше похоже на HTML Application.


                То есть мы возвращаемся в лехие нулевые и ухищряемся всеми возможными способами, чтобы попасть в тот самый IE 8, который будет стандартным WebView на Windows.
                  0
                  Да, вы правы. В том смысле, что HTA — это как раз пример того, какую роль десктопный JS должен играть. И Neutralinojs выглядит хорошим, годным кроссплатформенным HTA. Однако Electon выглядит чем-то куда боле монструозным.

                  мы возвращаемся в лихие нулевые и ухищряемся всеми возможными способами, чтобы попасть в тот самый IE 8, который будет стандартным WebView на Windows


                  В каком Windows? В новых виндах вроде будет клон хромиума в качестве браузера (хотя я то лично окончательно ушёл на Linux ещё в сравнительно благословенные времена Windows 7, сужу по новостям) и мне их Edge (который вроде бы пришёл на смену потомкам IE8) даже как-то жаль (во всяком случае исходники ChakraCore выглядят симпатично).

                  А так — ухищрения, как по мне, не чрезмерные. HTA? Да — HTA, при том, что броузер (как в общем-то для кроссплатформенного HTA логично) будет зависеть от конкретной версии конкретной ОСи. Ну так пишущий на HTML+JS как-то обязан уметь в кроссброузерность. Иначе лучше взять что-то другое, от Tcl/Tk до Qt (ну и .Net со временем обещает слиться, ага, в экстазе, c Mono и стоть по настоящему кроссплатформенным).

                  PS. Мне когда-то идея мозилловского XUL-а нравилась, но увы и ах — всё закончилось тем, что сама Mozilla выбросила эту технологию на помойку, и кто и как будет её поддерживать (и будет ли вообще) — сильно не ясно. ActiveState с их Komodo IDE вроде и не пытаются мозилловское ядро актуализировать, превращаясь в лютое legacy (как и Zotero), волчата из MoonChild серьёзным игроком не выглядят… Потому HTA — да, но привязка к любому конкретному броузерному движку — зло.
                +1
                1. По поводу памяти — так и не понял, почему должно есть меньше памяти. Ведь браузер или webview или что-то ещё всё-таки запускаются. Единственное, что не запускается — node.js, но тут как раз и минус — теряем стандартные API. Может быть фишка в том, что мы открываем как бы новую вкладку, а не браузер целиком, не тратя память на UI браузера и прочие плюшки? Если да, то Electron не доработан, т. к. это всё должно быть вырезано из браузера для экономии (что впрочем пока не отменяет преимущества Neutralino.js).
                2. Почему бы вместо стандартного браузера не сделать поиск браузеров и выбрать самый лучший? Поиск — очень быстрая операция, долстаточно проверить папки Program files, Program files (x86), AppData/Local и ветку реестра с установленными программами. Вложенные ветки или папки проверять не нужно. После поиска браузера сохранить результат, чтобы второй раз искать не пришлось. Также дать возможность пользователю изменить выбор. А автор приложения просто напишет что-то типа «Требования: установленный Google Chrome версии 62 и более».
                3. Возможно, те задачи, которые решает Neutralino.js, мог бы решать GraalVM (полностью совместимый аналог node.js) + GTK+ либо node.js + GTK+, юзая биндинги. При этом сохранился бы нодовский API, а пользователь бы получил приложение с действительно нативным интерфейсом, занимающее мало места и мало памяти (в несколько раз меньше, чем самое простое приложение на Electron).
                  0
                  Может быть фишка в том, что мы открываем как бы новую вкладку, а не браузер целиком, не тратя память на UI браузера и прочие плюшки?

                  Так, как раз было, в Chrome с поддержкой Chrome App, но Гугл, к сожалению, по непонятным причинам свернул этот функционал.
                  0
                  Сервер запускается сразу и является настоящим партизаном в тылу ОС. Он умеет хранить данные, открывать файлы, писать в файлы, запускать крипторы shell-команды. Собственно он делает всё, что может понадобиться, предоставляет API для операционки и общается с помощью HTTP с клиентом. Так же он отдаёт клиенту всё, что тот должен отобразить на экране. Достаточно стандартная функциональность для сервера.
                  А?!
                  нет вы серьезно? HTTP протокол не делает различий между веб-клиентами! Тем более если ожидается что вебклиентом будет стандартный браузер! Какими механизмами этот всемогущий сервер, дающий доступ ко всему и вся от имени текущего пользователя, будет защищать компьютер от злонамеренных веб-приложений, запущенных в соседней вкладке?

                  Дополнительные механизмы авторизации? Усложнение механизмов установки приложения (токен авторизации выдается в этот момент) и прочее? Какой-нибудь нестандартный механизм, отличный от уже существующих систем установки приложений на компьютер (linux) Т.е. через некоторое время установка приложений превратится в очередной виндовый да да разрешить принять согласиться некст некст…
                    0

                    О безопасности тут речи конечно же не идёт. Единственное препятствие в режиме window это token, который генерируется 1 раз на сессию и вшивается во все html страницы этим самым сервером.
                    Узнать этот token не составит труда никому, так что остаётся надеется только на фаервол.

                    0
                    Ну и давайте немного про интеграцию с ОС. Вспомним, что Electron и даже NW предлагали возможность создания своих Context Menu, разрешали скрывать окно и даже создавать иконку в трее. Тут этого всего просто нет. И, учитывая архитектуру решения, никогда не будет. Только браузер и только REST API, только хардкор.


                    Что касается иконки в трее, то ничто не мешает создавать её из «прослойки»-HTTP сервера.

                    Что действительно сложно сделать в данной архитектуре — это создание многооконных приложений (которые можно делать в ElectronJS), где приложение может задавать позиции и размер создаваемых окон.

                    Кстати, судя по активности в githab, проект заброшен (https://github.com/neutralinojs/neutralinojs/pulse/monthly)

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

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