- Построение Electron приложения. Введение
- Основные отличия
- Принцип работы
- Возможности Electron
- Настройка окружения
- Настройка WebStorm
- Первое приложение
- Распространение приложения
- Список литературы
- Пишем настольное JS-приложение с Electron
- Что из себя представляет Electron?
- Принимаемся за работу
- Архитектура приложения
- Что есть процесс?
- Основной процесс
- Процесс рендеринга
- Добавим индивидуальности
- Добавляем функциональность
- Дополняем приложение
- Тестируем, тестируем и ещё раз тестируем
Построение Electron приложения. Введение
Около года назад на Canonium вышла статья, в которой рассказывалось о построении node-webkit приложения. Эта статья стала одной из самых популярных у меня в блоге и даже пару раз мелькала в крупных пабликах в ВК, приводя всё больше и больше читателей.
С того времени изменилось многое: от Node.js отделился io.js, node-webkit сменил имя на nw.js, GitHub выпустил стабильную версию своего редактора кода Atom, а вскоре случилось явление Electron широкой публике.
Если говорить кратко, то Electron — это альтернатива NW.js, представляющая собой среду выполнения для построения настольных приложений, написанных, разумеется, на JavaScript.
Нужно заметить, что Electron предоставляет практически равные с NW.js возможности, кроме некоторых особенностей, о которых в рамках этой серии статей я говорить не буду. Следует сказать, что Electron обладает более сдержанной и качественной документацией, которую хочется читать, в отличие от того же NW.js.
Основные отличия
Далее Electron я буду называть «Электроном».
Ни для кого не секрет, что io.js вернулся в состав Node.js, который теперь регулируется Linux Foundation. Дело в том, что io.js сыграл злую шутку с NW.js, поманив его создателя на свою сторону. Создатели Электрона тоже не оставались в стороне, но, к счастью, уже успели вернуться на Node.js и успешно его поддерживают, в то время как NW.js 12-ой и 13-ой версии всё ещё базируются на io.js, причем не первой свежести.
В NW.js главный файл — это html-файл, указанный в package.json , в то же время в Электроне главным файлом является сценарий, написанный на JavaScript. Это позволяет писать приложения, скажем так, на более низком уровне, не прибегая лишний раз к скриптам в самом браузере. На самом деле, говорить так не совсем корректно, но таким образом упрощается маршрутизация по страницам внутри приложения. Как говорится в документации, в какой-то мере Электрон здесь представляет собой подобие Node.js.
GitHub создал Atom. Вместе с Atom родился Atom Shell. Atom Shell переродился в Электрон. В этой небольшой цепочке событий есть ключевое слово — GitHub. Да, Intel поддерживает NW.js, да, NW.js медленно, но развивается. Однако, GitHub будет поддерживать свою разработку столько, сколько будет существовать редактор Atom.
На самом деле, это не все отличия Электрона от NW.js, есть и другие — более технические. С полным списком можно ознакомиться в документации проекта.
Принцип работы
Принцип работы Электрона основан на двух типах процессов:
Первый тип — основной процесс, который отвечает за интеграцию и взаимодействие с GUI операционной системы. Под этим понятием скрывается интеграция в док на OS X или панель задач на Windows, а также сворачивание в трей, полноэкранный режим и прочие обыденные и нативные для ОС штуки. Такой процесс может быть запущен только один раз на всю жизнь приложения.
Второй тип — процесс рендеринга, отвечающий за отображение окна браузера, в котором с помощью одной магической строчки может быть открыта страница приложения или любая другая веб-страница. Таких процессов может быть произвольное число. За создание процесса рендеринга отвечает основной процесс.
Для того, чтобы породить основной процесс используется следующая схема рождения приложения:
- Электрон читает package.json и ищет в нём секцию main, в которой определен основной файл приложения. Этот файл далее в статье я буду называть «точкой входа».
- Затем происходит обработка «точки входа» и создаётся основной процесс, который в свою очередь, при желании разработчика, открывает какую-либо страницу или страницы, то есть создаёт окно браузера. А если говорить точнее, то порождает процесс или процессы рендеринга.
Если попытаться графически изобразить жизнь приложения, построенного на Электроне, то она будет иметь следующий вид:
Возможности Electron
Перед тем, как приступить к написанию js-файла, который будет выступать в роли точки входа для всего приложения, необходимо взглянуть на доступный разработчику API (набор модулей), чтобы позднее можно было ссылаться на модуль без приведения его описания.
Для компактности статьи я вынес описание доступных API Электрона версии 0.33.3 в отдельный Gist.
Настройка окружения
Думаю, не стоит упоминать, что для работы с Электроном вам нужен Node.js и пакетный менеджер npm актуальной версии. Кроме этого, я рекомендую глобально установить пакет electron-prebuilt, который позволит автоматически загружать актуальную версию Электрона и запускать приложения без необходимости предварительной сборки.
После установки пакет автоматически загрузит текущую стабильную версию Электрона. Теперь, для того, чтобы запустить приложение, необходимо всего лишь выполнить команду electron . в директории проекта. Для последующей автоматизации процесса разработки я советую добавить эту команду в секцию скриптов в package.json :
Эта запись даст возможность инициировать запуск приложения по команде npm start .
При желании можно загружать последнюю или любую другую версию Электрона вручную. Подробнее об этом написано в документации.
К слову, вы можете установить этот пакет локально, но в этом случае команда electron . преобразуется в страшный и некрасивый набор символов:
Кроме самого Электрона я также советую установить пакет XO, который является оберткой над ESLint:
ESLint является самым передовым линтером js-кода, разрабатываемый Николасом Закасом.
Настройка WebStorm
Из коробки WebStorm не умеет автоматически дополнять, предлагать методы, да и вообще работать с Electron. Чтобы исправить эту несправедливость нужно выполнить пару нехитрых операций.
Сначала необходимо перейти к настройке библиотек и фреймворков и, после этого, выбрать там наш любимый JavaScript:
Нажимаем кнопку Download и выбираем слева вверху канал пакетов TypeScript community stubs. Затем ищем в большом списке всякой всячины запись github-electron, выбираем её и кликаем на кнопку Download and install. Готово!
Для поиска по списку кликните на любом элементе списка и начните вводить интересующее вас слово.
Первое приложение
Первым шагом в начале разработки любого Node.js приложения будет создание файла package.json . Вы можете создать его в полуавтоматическом режиме с помощью команды npm init , отвечая на вопросы, или же вручную, добавив лишь самое нужное:
Так как я ещё не решил, что мы будем разрабатывать в течении всей серии статей, пока что приложение будет иметь имя app.
Теперь самое время выполнить команду, добавляющую в package.json поддержу js-линтера XO:
Эта команда автоматически добавит в package.json всё самое необходимое, а также установит локальную копию XO. Остаётся лишь добавить вызов XO в скрипт start, чтобы перед запуском приложения, написанный ранее js-код, всегда оставался чистым и хорошо пахнул:
Я также добавил и изменил несколько правил проверки кода, чтобы линтер соответствовал моим личным требованиям и был удобен в использовании.
Самое время создать какой-нибудь простенький html-файл, который в последствии будет загружаться при старте приложения. Как мне кажется, нет ничего лучше, чем вывести на экран версию Node.js, Electron и Chrome. Для этого обратимся к модулю process, который был расширен Electron. Теперь, помимо информации о текущем процессе, он также может предоставлять информацию о типе процесса (основной или рендер), версию Chrome и Electron, а также путь до исполняемого js-файла.
Забыл сказать, что при написании приложения я буду по возможности и желанию использовать некоторые фишки из ES2015 (ES6).
Файл main.js является «точкой входа» для всего приложения. В нём будут создаваться окна и обрабатываться системные события.
Сначала необходимо подключить модуль app, отвечающий за управление жизненным циклом приложения и browser-window, создающий новое окно браузера.
Далее создаётся ссылка на объект Window. Это делается для того, чтобы окно не закрывалось автоматически, когда объект будет обработан сборщиком мусора.
При закрытии всех окон приложения следует из него выйти. В OS X это событие является общим для приложений и их баров меню, поэтому здесь присутствует условие, отбрасывающее эту платформу.
После того, как Электрон полностью будет инициализирован, станет доступным API управления приложением. Ниже представлен код, который создаёт новое окно браузера размерами 800 на 600 пикселей. Затем в этом окне загружается ранее созданный нами html-файл.
Важно заметить, что даже если вы не загрузите ни один из html-файлов, процесс рендеринга всё равно будет запущен, так как ранее уже было создано окно браузера.
В конце вешается обработчик события closed, которое всплывает тогда, когда окно браузера уже было закрыто. После того, как вы получили данное событие, необходимо удалить ссылку на окно и больше его не использовать.
К слову, не стоит путать событие closed с похожим на него событием close, которое посылается, когда окно будет закрыто, то есть перед closed.
Вообще, тема событий в Электроне достойна отдельной статьи, но в силу моей лени, желающие могут обратиться к документации. Скажу лишь, что жизненный цикл приложения в событиях будет выглядеть следующим образом:
- will-finish-launching
- ready
- browser-window-created
- page-title-updated
- close
- before-quit
- will-quit
- quit
- window-all-closed
- closed
События, событиями, но вернемся к нашему приложению — самое время запустить его, используя команду npm start .
В итоге мы имеем окно, в котором отображается текущая версия Node.js, Electron и Chrome. Кроме того, окно приложениия имеет служебное меню с небольшим набором стандартных пунктов. Служебным оно называется из-за того, что после сборки проекта, как вы увидите позднее, оно исчезает.
Распространение приложения
В отличие от статьи про NW.js я дам самый необходимый материал сразу же в первой статье, чтобы самые активные читатели уже имели возможность начать изучать этот инструмент самостоятельно.
Для сборки приложения я предлагаю воспользоваться пакетом electron-packager. Сначала установим его глобально:
В этот раз мы обойдемся без планировщика задач, наподобие Grunt или Gulp. Мы же взрослые люди? — думаю, да!
Просто создадим новый скрипт build в package.json с таким содержанием:
Теперь, выполнив команду npm run build вы получите сборку своего приложения под операционную систему Windows. Если же вам необходима сборка под все три платформы, то команда будет иметь вид:
После сборки приложения под все три платформы будет создано, как это ни странно, пять директорий:
- app-darwin-x64
- app-linux-ia32
- app-linux-x64
- app-win32-ia32
- app-win32-x64
Но самое забавное, что полностью собранный «комплект» весит всего лишь каких-то жалких 500Мб.
Кроме явного указания имени приложения и версии Электрона в команде, можно воспользоваться данными из package.json . Создадим два поля, которые будут содержать имя публикуемого приложения и версию, с помощью которой необходимо будет собрать его:
После этого в команде станут доступны переменные:
Разумеется, что вам никто не запрещает использовать поле name как имя приложения:
В итоге команда может принять вид:
К сожалению, на Windows я так и не смог заставить electron-packager использовать $npm_package_* . Зато на OS X это замечательно работает.
Сейчас я предлагаю немного подробнее остановиться на аргументах, передаваемых в пакет electron-packager . Шаблон команды выглядит следующим образом:
Доступные для пользователя аргументы:
Обязательные
- platform — платформа ( all или win32 , linux , darwin )
- arch — разрядность ( all или ia32 , x64 )
- version — версия Электрона для сборки
Опциональные
- all — эквивалент —platform=all —arch=all
- out — директория, в которую будут помещены сборки
- icon — иконка приложения ( .icns или .ico )
- app-bundle-id — идентификатор приложения в plist
- app-version — версия приложения
- build-version — версия сборки приложения для OS X
- cache — директория, в которой будет располагаться кэш приложения
- helper-bundle-id — идентификатор приложения для помощника plist
- ignore — исключение файлов из сборки
- prune — запуск команды npm prune —production в приложении
- overwrite — перезапись уже созданных сборок
- asar — упаковка исходников приложения в asar-архив
- asar-unpack — распаковка указанных файлов в директорию app.asar.unpacked
- sign — идентификатор для входа в codesign (OS X)
- version-string — ключи для сборки (Windows). Список ключей смотрите в документации пакета
О том, как добавлять иконки, что вообще следует делать перед распространением приложения и как создать установщик для сборки, я расскажу в заключительной части этой серии статей.
Список литературы
По традиции оставляю ссылки на то, что можно почитать, чтобы расширить свой кругозор в рамках этой статьи. На русском языке ничего нет, так как у нас Электрон как-то не особо популярен.
Статьи
Модули
Делимся на оплату хостинга или кофе.
Чем чаще пью кофе, тем чаще пишу статьи.
Источник
Пишем настольное JS-приложение с Electron
Задавались ли вы когда-нибудь вопросом, возможно ли создавать кроссплатформенные настольные приложения на HTML, CSS и JavaScript? С Electron это становится возможным. В этой статье мы рассмотрим основы Electron и напишем простое приложение.
Функциональность нашего приложения будет заключаться в том, что при нажатии определённой клавиши на клавиатуре будет воспроизводиться соответствующий звук.
Прим. перев. Для создания приложений с использованием Electron не требуется знание таких языков программирования, как C++ и Python, — знания веб-технологий будет достаточно. Если вы не ограничены веб-технологиями, хорошей альтернативой использованию Electron будут GTK+ и Qt: в отличие от «родных» приложений, приложения, написанные с использованием Electron, обладают множеством недостатков, в том числе крайне неэффективно используют свободную оперативную память компьютера. Статью по QT можно посмотреть у нас на сайте.
Что из себя представляет Electron?
Electron — фреймворк для кроссплатформенной разработки настольных приложений с использованием Chromium и Node.js.
С его помощью можно легко написать приложение с использованием HTML, CSS и JavaScript, которое «из коробки» будет совместимо с Mac, Windows и Linux.
Компания «ОС3» , Москва, можно удалённо , По итогам собеседования
Другие встроенные особенности включают:
- Автоматические обновления приложений;
- Нативные меню и уведомления;
- Сообщения об ошибках, которые можно отправлять на удалённый сервер;
- Отладка и профилирование — модуль content Chromium ищет места, где проседает производительность. Вы также можете использовать инструменты разработчика в своём приложении;
- Быстрое и простое создание установочных пакетов для Windows.
Если вы довольны тем, что предлагает Electron, то давайте займёмся нашим приложением. Однако прежде чем мы начнём, необходимо установить Node.js. Также вам пригодится аккаунт на GitHub, чтобы хранить и обновлять своё приложение. Это делать необязательно, но желательно, так как в наше время важно знать, как работает GitHub.
Принимаемся за работу
Когда вы закончите с подготовкой, откройте терминал и следуйте дальнейшим инструкциям, чтобы клонировать репозиторий Electron Quick Start на ваш компьютер. Именно на основе Electron Quick Start мы и будем писать наше приложение.
После выполнения этих шагов приложение должно запуститься в чём-то, похожем на окно браузера. Хотя, это и есть окно браузера!
Как было сказано ранее, в своём приложении вы можете использовать инструменты разработчика. Всё, что вы можете делать с инструментами вашего браузера, вы также можете делать и в приложении. Потрясающе!
Архитектура приложения
Теперь давайте взглянем на код и структуру приложения.
Структура самая обычная, очень похожая на ту, что используется при создании веб-страниц. У нас есть:
- index.html — HTML-страница, отвечает за внешний вид;
- main.js — создаёт окна и управляет системными событиями;
- package.json — описание пакета (имя, зависимости и т.д.) для npm;
- renderer.js — управляет процессами рендеринга.
Возможно, вы задаётесь вопросом: «Что за звери эти процессы рендеринга и основной процесс?» Давайте разбираться.
Что есть процесс?
Когда вы видите слово «процесс», думайте о процессе в операционной системе. По сути, это экземпляр программы, работающей в системе.
Если запустить наше Electron-приложение и заглянуть в Диспетчер Задач в Windows, Мониторинг Активности в macOS или Системный Монитор в Linux, то можно увидеть процессы, связанные с приложением.
Все они работают параллельно, однако память и ресурсы, выделенные под каждый из них, изолированы от других процессов.
Допустим, мы хотим написать цикл в процессе рендеринга:
Этот код никак не повлияет на основной процесс.
Основной процесс
Этот процесс контролирует происходящее в приложении. В него встроен полноценный Node.js API. Из него создаются процессы рендеринга и открываются диалоговые окна. Также он отвечает за разное взаимодействие с операционной системой, запускает и закрывает приложение.
Файл с этим процессом принято называть main.js , но вы можете дать ему любое имя. Также вы можете менять файл основного процесса через package.json . Чтобы проверить, как это работает, откройте файл package.json , замените строку «main»: «main.js» на «main»: «mainTest.js» и попробуйте запустить приложение.
Имейте в виду, что основной процесс может быть только один.
Процесс рендеринга
Этот процесс представляет собой окно браузера в вашем приложении. В отличие от основного процесса, процессов рендеринга может быть несколько и каждый из них будет независим от остальных. За счёт этого ошибка в одном из них никак не повлияет на другие. Скажем за это спасибо многопроцессорной архитектуре Chromium. Также эти окна можно спрятать или изменить, так как они работают как HTML-файлы.
Но в Electron у нас также есть доступ к Node.js API. Это значит, что мы можем открывать диалоговые окна и взаимодействовать с операционной системой прочими способами.
Представить происходящее можно следующим образом:
Остаётся один вопрос. Можно ли как-нибудь связать эти процессы?
Эти процессы выполняются одновременно и независимо. Однако им всё равно нужно как-то взаимодействовать. Особенно учитывая то, что они отвечают за разные задачи.
Специально для таких целей существует межпроцессное взаимодействие (IPC). Его можно использовать для передачи сообщений между основным процессом и процессами рендеринга.
Вот мы и разобрались с основами процессов для создания Electron-приложения. Возвращаемся к коду!
Добавим индивидуальности
Поменяем название папки с нашим приложением на более подходящее. Измените название папки с electron-quick-start на hear-me-type-tutorial . Откройте папку заново в текстовом редакторе или IDE. Теперь похимичим с файлом package.json . Он содержит важную информацию о нашем приложении: имя, версию, автора, лицензию и многое другое.
Давайте укажем, кто является автором приложения. Для этого найдите параметр author и замените его значение на своё имя. Должно получиться что-то такое: «author»: «Carol Pelu» . Также вы можете изменить и другие параметры вроде name и description , которые отвечают за название приложения и его описание соответственно. В итоге должно получиться примерно так:
Помните, что вы всегда можете ввести npm start в терминале, чтобы запустить приложение и посмотреть на внесённые изменения.
Пора идти дальше и добавить в наше приложение функциональность.
Добавляем функциональность
Мы хотим, чтобы при нажатии клавиши на клавиатуре проигрывался соответствующий звук. Чтобы реагировать на пользовательский ввод, мы должны определить элемент, который будет перехватывать нажатия клавиш и затем активировать нужное действие.
Для этого мы создадим элементы audio со своим id для каждой клавиши. Затем напишем switch-конструкцию, чтобы понять, какая клавиша была нажата. После этого воспроизведём звук, привязанный к этой клавише. Если это звучит сложно — не беспокойтесь, мы разберёмся со всем пошагово.
Скачайте этот архив с нужными нам аудиофайлами. Пора встраивать аудио в наше приложение.
Откройте index.html и внутри создайте новый элемент
Затем внутри этого
Мы используем preload=»auto» , чтобы сказать приложению, что оно должно загрузить весь аудиофайл после загрузки страницы. Главным файлом нашего приложения является index.html , и все аудио загрузятся после запуска приложения.
В итоге код должен выглядеть так:
Теперь index.html имеет примерно такой вид:
Отлично! Теперь нам не хватает только JavaScript-кода.
Создадим новый файл functions.js . Давайте запросим его в файле index.html , чтобы JS-код был готов к использованию, когда приложение будет запущено.
Следуя примеру require(./renderer.js’) , добавим строку require(‘./functions.js’) прямо под ней.
Проект теперь должен иметь такой вид:
Отлично! Теперь, когда уже почти всё готово, наступает момент истины.
Откроем functions.js и добавим туда следующий код:
Откройте консоль, убедитесь, что вы находитесь в директории проекта и введите npm start для запуска приложения.
Сделайте звук погромче и нажмите клавишу «А» на клавиатуре.
JS-код довольно простой. Мы используем событие onkeydown для объекта document , чтобы выяснить, к какому HTML-элементу мы обращаемся. Имейте в виду, что объектом document является главное окно нашего приложения.
В анонимной функции мы используем switch-выражение, которое выясняет Unicode-значение нажатой клавиши. Если это значение правильное, то воспроизводится звук. В противном случае в консоль выводится сообщение: «Клавиша не обнаружена!».
Как вы могли заметить, у нас есть файлы для клавиш от A до Z и от 0 до 9. Поэтому давайте используем и их, чтобы «А» было не так одиноко.
Потрясающе! Теперь давайте провернём то же самое в functions.js .
Код для каждой клавиши можно найти здесь. Но вы по-прежнему можете просто скопировать:
Прим. перев. Как вы, вероятно, заметили, такая switch-case конструкция выглядит довольно громоздко. А как вы бы оптимизировали этот участок кода? Делитесь своими вариантами в комментариях.
Вот мы и закончили наше приложение! Поздравляем!
Основная функциональность в приложении присутствует, но его ещё можно доработать.
Дополняем приложение
Да, у нас всё работает, но всё равно то тут, то там чего-то не хватает. Например, в index.html вы можете изменить заголовок приложения и содержимое основного окна. Кроме того, у нас нет никакого дизайна, нет красивых цветов и нет картинок с котиками. Включите воображение и попробуйте улучшить внешний вид приложения.
Код тоже не верх совершенства. У нас куча одинакового кода, который можно оптимизировать и улучшить. В итоге код будет занимать меньше места, и глазам будет не так больно. Помните: повторяющийся код — это плохо.
Тестируем, тестируем и ещё раз тестируем
Хорошее ПО должно быть тщательно протестировано. Попробуйте нажать каждую клавишу, чтобы увидеть, что произойдёт. В лучшем случае вы услышите звук для каждой клавиши, указанной в коде. Но что если вы нажмёте много клавиш подряд так быстро, как только можете? А что насчёт клавиш вроде Home и NumLock, для которых у нас нет звука?
Если вы свернёте приложение и нажмёте клавишу, вы услышите звук? А если окно приложения неактивно, и вы нажмёте клавишу, то что-нибудь произойдёт?
К сожалению, ответ — нет.
Так происходит из-за архитектуры, на которой построен Electron. Вы можете регистрировать нажатия клавиш внутри приложения как в C#, но не можете этого делать за его пределами. Это выходит за рамки привычных Electron-приложений.
Пройдитесь по коду строка за строкой и попробуйте сделать его нерабочим. Посмотрите, что произойдёт и какие ошибки выбросит Electron. Это упражнение поможет вам разобраться в отладке. Если вы знаете слабые места своего приложения, то вы знаете, как их исправить и сделать приложение лучше.
В файле functions.js было использовано устаревшее событие. Сможете его найти? Когда найдёте, подумайте, как его заменить без изменения функциональности приложения.
Использование устаревшего кода — плохая практика. Это может привести к серьёзным багам, о существовании которых вы могли даже не подозревать. Следите за документацией языка, чтобы знать, какие произошли изменения. Всегда будьте в курсе последних событий.
Хинт для программистов: если зарегистрируетесь на соревнования Huawei Cup, то бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.
Перейти к регистрации
Источник