Electron — создание десктопного приложения с помощью веб-технологий
В данной статье мы расскажем, что такое Electron, как решать проблемы с закрытием процесса визуализации, как передавать информацию из основного процесса в процесс визуализации, а также как предотвратить запуск более одного экземпляра Electron-приложения.
Что такое Electron
Electron — библиотека с открытым исходным кодом, разработанная GitHub, позволяет разрабатывать нативные графические приложения для десктопных операционных систем с помощью веб-технологий: HTML, CSS, и JavaScript. Electron достигает этого путем объединения Chromium и Node.js в единую среду выполнения, а приложения могут быть собраны для выполнения под Mac, Windows и Linux.
Стоит отметить преимущество, которое нам даёт разработка десктопных приложений с помощью Electron — лёгкое создание пользовательского интерфейса с помощью веб-технологий и богатый API, благодаря которому можно создавать и настраивать окно приложения под любые нужды.
Давайте рассмотрим как работает и из чего состоит Electron-приложение.
В Electron-приложении существует два типа процессов: основной процесс и процесс визуализации.
Основной процесс (main process) — это процесс, который запускается из package.json. Скрипт, запущенный в основном процессе, может отображать GUI используя веб-страницы. В Electron-приложении всегда есть один главный main process. Основной процесс управляет процессами визуализации.
Процесс визуализации (renderer process) отвечает за запуск пользовательского интерфейса вашего приложения, или, другими словами, веб-страницы, являющейся экземпляром webContents (отвечает за рендеринг и управление веб-страницей). Все API-интерфейсы DOM, API-интерфейсы node.js и подмножество API библиотек Electron доступны в данном процессе.
Решение проблемы с закрытием процесса рендеринга
Из-за многопроцессорной архитектуры Chromium мы столкнулись с проблемой, что при закрытии или аварии в процессе визуализации, приложение продолжает выполняться, но в окне ничего не отображается (процесс визуализации мертв), однако нам было необходимо, чтобы процесс визуализации работал постоянно.
Решением данной проблемы является перехват события ‘crashed’ (возникает при сбое или завершении процесса рендеринга) для объекта webContents, который можно получить из BrowseWindow (класс, который дает возможность создать окно браузера).
Пример закрытия приложения при аварии в render process:
browseWindow.webContents.on('crashed', () => { app.exit() })
Передача информации в основной процесс из процесса визуализации
В Electron некоторые графические модули(например: меню, формат окна приложения, размер, прозрачность и т.д.) доступны только в основном процессе, но не в процессе визуализации. Управление этими модулями из процесса визуализации осуществляется при помощи модуля ipc, этот модуль позволяет отправлять асинхронные межпроцессорные сообщения.
Для большей наглядности продемонстрируем вызов функциональности основного процесса из процесса визуализации на примере. При нажатии пользователем на кнопку «выйти», приложение должно перейти в режим киоска — пользовательский интерфейс, который ограничивает доступ к функционалу приложения и системы. В решении поставленной задачи используем модули ipcMain и ipcRenderer.
Модуль ipcMain обрабатывает асинхронные и синхронные сообщения, отправленные из процесса визуализации в основном процессе. Для этого воспользуемся методом on(channel, listener), который слушает канал channel, и при появлении нового сообщения вызовется listener.
Ниже приведен пример кода, который слушает канал ‘logout’ на появление новых сообщений, и при появлении нового сообщения переведёт приложение в режим киоска:
const {ipcMain} = require('electron'); ipcMain.on('logout', () => { mainWindow.setKiosk(true); });
Модуль ipcRenderer позволяет отправлять асинхронные и синхронные сообщения из процесса визуализации в основной процесс.
Нами была реализована функция userLogout, которая отвечает за логику завершения сеанса пользователя. В числе прочего, сделаем сигнал(отправим пустое сообщение) о переходе приложения в режиме киоска, по каналу ‘logout’:
export const userLogout = () => { // other logic ipcRenderer.send('logout'); };
Предотвращение запуска более одного экземпляра Electron-приложения
Для того, чтобы предотвратить запуск более одного экземпляра Electron-приложения, существует метод makeSingleInstance из модуля app, который возвращает значение true — в случае, если текущее приложение является не первым запущенным экземпляром, и false — в случае, если первым.
В OS X система автоматически сконфигурирована на то, что пользователь не может запустить больше одного экземпляра приложения. В случае запуска второго экземпляра приложения, оно будет закрыто. Однако механизм единственного экземпляра в OS X не работает, когда пользователь запускает приложение из командной строки. Чтобы Electron-приложению добиться единственного экземпляра в OS X, нужно добавить в приложение код, приведенный ниже. Когда происходит старт второго экземпляра он блокируется и фокус происходит на запущенный первый экземпляр Electron-приложения.
let shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => { if (mainWindow) { if (mainWindow.isMinimized()) mainWindow.restore(); mainWindow.focus(); } }); if (shouldQuit) { app.quit(); return; }
Заключение
Electron является конкурентоспособным решением при разработке кроссплатформенных приложений. Не требует от команды разработки знания таких языков программирования как C++ и Python, позволяет создавать приложения, используя богатые возможности веб-технологий HTML, CSS, JS, а также Node.js.
Главная причина, почему Electron настолько популярен: не нужно переписывать уже написанное. Имея уже веб-приложение, вам не потребуется много сил для перевода его на Electron. Electron из коробки предоставляет разнообразный функционал по работе с окном приложения. Также большим преимуществом фреймворка является то, что этот проект распространяется как open source и имеет активное комьюнити.
Главным недостатком Electron является большое потребление оперативной памяти и большой вес даже минимального приложения.