Electron. Как работает самый современный desktop framework
Что почувствует разработчик, если ему\ей предложат написать desktop приложение? Он\Она наверняка расстроится. Ведь desktop видится нам в эру браузеров и интернета чем-то отсталым и ненужным. Но что делать если наш софт должен работать без интернета, на слабой машине и и при этом мог быть установлен одним кликом мыши? Учить морально и физически устаревшие фреймворки типа WPF явно не вариант, ведь их потом негде будет применить. Да и в поддержке они не всегда хороши, особенно с учетом того что желающих это делать точно не стоит очередь.
В таких случаях нам на помощь придет ̶M̶r̶.̶ ̶P̶r̶o̶p̶e̶r̶ Electron. Кроссплатформенный JavaScript фреймворк с которым справится при небольшой подготовке любой front developer. В своем портфолио Electron имеет много популярных программ, таких как MS Teams, VS Code, Skype, Spotify, WhatsApp и т.д. Electron разработан и поддерживается GitHub, а так же имеет больше комьюнити.
Меня зовут Алексей Голубев, я работаю с Electron порядка 2х лет. И сейчас мы немного поговорим о том, почему топовые компании выбирают этот инструмент для своих приложений.
А что под капотом?
В Electron можно выделить две основные части.
- Main process. Main отвечает за создание браузерных окон и взаимодействие с операционной системой. Физически это NodeJS.
- Renderer process. Каждое браузерное окно запускает веб страницу в своем renderer process. При этом несколько renderer могут между собой общаться, но никак не влияют друг на друга. Это по сути Chromium. Но мы его видим как окно обычного приложения.
Общается это все безобразие между собой по IPC.
Схема потоков Electron
При таком количестве взаимосвязанных частей все это выглядит довольно нестабильно, однако это лишь на первый взгляд. Например, краш одного из renderer никак не повлияет на соседние renderer и приложение продолжит работу. К тому же как правило используются последние стабильные версии NodeJS и Chromium. Из опыта — крашится эта штука крайне редко и работает стабильно, несмотря на солянку из слоев.
Стоит отметить что с виду это очень похоже на модель «клиент-сервер», но это только на первый взгляд. На самом деле NodeJS (main process) прослойка здесь нужна только для взаимодействия с ОС и вызывать мы ее можем из renderer процесса. Если упростить, то управлять файлами на диске можно прям в ангуляровской компоненте. Поэтому принято использовать main процесс исключительно для запуска окон, установки апдейтов и других вещей которые следует сделать при запуске.
А сколько ест?
Кроссплатформенность еще никому не давалась дешево и за все нужно платить. С Electron мы платим накладными расходами за висящую в памяти NodeJS и Chromium (70 мб). Дальше уже начинаются расходы приложения и если вы не сильно абузите API операционной системы то ваше приложение скушает по памяти и CPU сравнимые с обычным браузером цифры.
К этому стоит добавить довольно объемный установочный файл
В целом для современных машин это не много, учитывая что после накладных расходов на запуск приложение кушает так же как и в стоковом браузере.
Скриншот Spotify на пике при переключении треков
А как насчет производительности?
Из коробки все работает силами Chromium со всеми его преимуществами и недостатками. Это и JS движок, и однопоточность, и песочница которая изолирует нас от операционной системы.
Если же вам этого не хватает вы можете запускать силами NodeJS child process. Так делают многие вендоры, наглядней всего это выглядит у VS Code.
Visual Studio Code умеет интегрироваться с консольными утилитами, подключать дебаггер, запускать линтер и все в отдельных процессах.
А такие бибилиотеки как Electron.NET позволяют запустит дочерним полноценный .NET Core и общаться с ним как с обычное клиент-серверное приложение. Таким образом в 1 клик по инсталлеру мы можем разместить на компьютере пользователя и клиент, и сервер, и портативную БД. Таким образом превратив, например, наше классическое веб приложение в десктоп.
Скрин процессов простаивающего Electron.NETприложения.
Есть еще одна особенность NodeJS которую мы можем использовать — импорт C/C++ библиотек (Native Addon), как это делает например Skype. Skype использует библиотеки по работе с медиа, кодеками и прочими вещами, которые довольно проблематично поддерживать вне C/C++.
А как с дебагом и автотестируемостью?
Как мы уже обсудили, есть 2 основных процесса — main и renderer. Их мы и можем дебажить, раздельно естественно.
Для дебага main достаточно запустить Electron с открытым портом под дебаг примерно так же как это делается в NodeJS и подключиться дебагером, например VS Code.
Дебаг renderer чуть сложнее и вариативней. Так как это по сути браузер то нам доступно 2 способа — подключиться к открытому порту для дебага либо открыть DevTools. Если вы используете WebPack, то учитывайте наличие source-map файлов в конечном бандле. К тому же у WebPack есть специальные target «electron-renderer» и «electron-main».
Скриншот открытого DevTools в Electron приложении
На этом этапе тесты можно разделить на 2 типа.
- Инфраструктурные. В случае с десктоп приложение мы отвечаем не только за работу приложения, но и за его установку, запуск, доставку, апдейд, удаление и т.д. Тут автотестеру придется освоить новые трюки, но особо проблем быть не должно, разве что с кроссплатформенностью. Либо же оставить эти тесты мануальными.
- Тесты приложения. И здесь все хорошо. Electron поддерживается многими фреймворками и документация изобилует примерами. Есть поддержка Selenium и WebDriver, Headless CI Systems (Travis, Jenkins). А если вам и этого мало, то можно использовать даже расширения для DevTools. Ваш тестировщик\тестировщица скорее всего довольно быстро разберется и не заметит особой разницы с веб приложением.
А есть ли подводные камни?
Подводные камни как и в любом проекте есть. Например версионирование. Вначале проект развивался довольно неспешно и мажорные версии выходили редко. Сейчас за ними не угнаться. Версия 11.0.0 вышла спустя 3 месяца после 10.0.0. При том что версия 3.0.0 вышла только спустя год после 2.0.0.
Многие версии включая версию 1(1.8.8) до сих пор получают обновления. Однако при обновлении на мажорную версию листайте ченжлог. К сожалению такой удобной миграции как в Angular не завезли и что-то может сломаться просто потому что какой-то из дефолтных флагов стал false вместо true.
Как писалось выше, мы делаем все операции бизнес логики делаем в renderer, т.е. на фронте мы можем вызывать fs и юзать диск, или ходить по ссылкам на другие ресурсы. Часто в таких случаях мы подключаем вспомогательные библиотеки которые могут быть рассчитаны на NodeJS, а не браузер. Поэтому вести они могут себя не так, как мы того ожидаем. При добавлении новых библиотек всегда есть шанс что нужно будет модифицировать конфиг webpack.
И что в итоге?
В итоге мы имеем:
- кроссплатформенный JS фреймворк
- мощный и расширяемый как нативными модулями, так и подпроцессами
- не требователен к компетенции разработчиков, нам хватит front-end с хорошим знанием JS
- совместим с TypeScript
- имеет большое комьюнити и обширную библиотеку вспомогательных пакетов
Electron своей простотой и низким порогом входа постепенно вытесняет другие решения в десктопной разработке. Безусловно у фреймворка есть свои нюансы, которые нужно знать и работа с ним, как и с любым другим столь мощным современным инструментом, не будет легкой прогулкой. Однако, на данный моменту нас почти нет альтернатив, которые обеспечат то же качество и скорость разработки. Да и всем удобней, когда мы имеем на веб сайте и десктоп приложении теже UI/UX решения.
А что вы думаете по этому поводу? Как перенести красоту и функциональность наших веб сайтов в десктоп или этого не стоит вообще делать?
Найкращі коментарі пропустити