пишем приложение на electron
Руководство для начинающих
К концу этого урока ваше приложение откроет окно браузера, отображая веб-страницу с информацией о том, какие версии Chromium.js Node и Electron работают.
Prerequisites
Чтобы использовать Electron вы должны установить Node.js. Мы рекомендуем Вам использовать последнюю доступную LTS версию.
Пожалуйста, установите Node.js с помощью предварительно собранных установщиков для вашей платформы. В противном случае могут возникнуть проблемы совместимости.
Чтобы убедится что Node.js был установлен правильно, напишите следующие команды в терминале:
Команды должны вывести версии Node.js и npm соответственно.
Note:Так как Electron встраивает Node.js в двоичный код, выполняемая версия Node.js может отличатся.
Создание приложения
Сборка приложения
Приложения Electron имеют ту же общую структуру, что и другие проекты Node.js. Начните с создания папки и инициализации пакета npm.
Команда init запросит некоторые значения для файла конфигурации. В этом туториале стоит придерживаться следующего:
Ваш package.json файл должен выглядеть примерно так:
Примечание: Если у вас возникли какие-либо проблемы с установкой Electron, пожалуйста, обратитесь к руководству Advanced Installation.
Эта start команда откроет ваше приложение в режиме разработчика.
Примечание: Эта команда запускает приложение из корневой папки. На этом шаге возможна ошибка, которая заключается в том, что не найдено приложение для запуска.
Запуск main process
В процессе выполнения, Electron будет искать этот скрипт в основном поле вашего package.json конфига, который вы сконфигурировали в процессе формирования кода приложения.
Чтобы инициализировать основной скрипт, создайте пустой файл с именем main.js в корневой папке вашего проекта.
Создание веб-страницы
Прежде чем мы сможем создать окно для нашего приложения, нам нужно создать контент, который будет загружен в него. В Electron каждое окно отображает веб-содержимое, которое может быть загружено из локального HTML файла или удаленного URL.
В этом туториале вы будете создавать первое. Создайте index.html файл в корневой папке проекта:
Замечание: Посмотрев на этот HTML-документ, можно заметить, что версии не указаны в блоке body. Мы вручную вставим их позже с помощью JavaScript.
Открытие веб-страницы в окне браузера
Now that you have a web page, load it into an application window. To do so, you’ll need two Electron modules:
Because the main process runs Node.js, you can import these as CommonJS modules at the top of your file:
Then, add a createWindow() function that loads index.html into a new BrowserWindow instance.
Next, call this createWindow() function to open your window.
In Electron, browser windows can only be created after the app module’s ready event is fired. You can wait for this event by using the app.whenReady() API. Call createWindow() after whenReady() resolves its Promise.
Note: At this point, your Electron application should successfully open a window that displays your web page!
Manage your window’s lifecycle
Although you can now open a browser window, you’ll need some additional boilerplate code to make it feel more native to each platform. Application windows behave differently on each OS, and Electron puts the responsibility on developers to implement these conventions in their app.
In general, you can use the process global’s platform attribute to run code specifically for certain operating systems.
Quit the app when all windows are closed (Windows & Linux)
On Windows and Linux, exiting all windows generally quits an application entirely.
To implement this, listen for the app module’s ‘window-all-closed’ event, and call app.quit() if the user is not on macOS ( darwin ).
Open a window if none are open (macOS)
Whereas Linux and Windows apps quit when they have no windows open, macOS apps generally continue running even without any windows open, and activating the app when no windows are available should open a new one.
To implement this feature, listen for the app module’s activate event, and call your existing createWindow() method if no browser windows are open.
Because windows cannot be created before the ready event, you should only listen for activate events after your app is initialized. Do this by attaching your event listener from within your existing whenReady() callback.
Note: At this point, your window controls should be fully functional!
Access Node.js from the renderer with a preload script
Now, the last thing to do is print out the version numbers for Electron and its dependencies onto your web page.
Accessing this information is trivial to do in the main process through Node’s global process object. However, you can’t just edit the DOM from the main process because it has no access to the renderer’s document context. They’re in entirely different processes!
Note: If you need a more in-depth look at Electron processes, see the Process Model document.
This is where attaching a preload script to your renderer comes in handy. A preload script runs before the renderer process is loaded, and has access to both renderer globals (e.g. window and document ) and a Node.js environment.
Create a new script named preload.js as such:
The above code accesses the Node.js process.versions object and runs a basic replaceText helper function to insert the version numbers into the HTML document.
To attach this script to your renderer process, pass in the path to your preload script to the webPreferences.preload option in your existing BrowserWindow constructor.
There are two Node.js concepts that are used here:
We use a path relative to the currently executing JavaScript file so that your relative path will work in both development and packaged mode.
Bonus: Add functionality to your web contents
At this point, you might be wondering how to add more functionality to your application.
For any interactions with your web contents, you want to add scripts to your renderer process. Because the renderer runs in a normal web environment, you can add a
Пишем настольное JS-приложение с Electron
Авторизуйтесь
Пишем настольное 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.
Другие встроенные особенности включают:
Если вы довольны тем, что предлагает Electron, то давайте займёмся нашим приложением. Однако прежде чем мы начнём, необходимо установить Node.js. Также вам пригодится аккаунт на GitHub, чтобы хранить и обновлять своё приложение. Это делать необязательно, но желательно, так как в наше время важно знать, как работает GitHub.
Принимаемся за работу
Когда вы закончите с подготовкой, откройте терминал и следуйте дальнейшим инструкциям, чтобы клонировать репозиторий Electron Quick Start на ваш компьютер. Именно на основе Electron Quick Start мы и будем писать наше приложение.
После выполнения этих шагов приложение должно запуститься в чём-то, похожем на окно браузера. Хотя, это и есть окно браузера!
Как было сказано ранее, в своём приложении вы можете использовать инструменты разработчика. Всё, что вы можете делать с инструментами вашего браузера, вы также можете делать и в приложении. Потрясающе!
Архитектура приложения
Теперь давайте взглянем на код и структуру приложения.
Структура самая обычная, очень похожая на ту, что используется при создании веб-страниц. У нас есть:
Возможно, вы задаётесь вопросом: «Что за звери эти процессы рендеринга и основной процесс?» Давайте разбираться.
Что есть процесс?
Когда вы видите слово «процесс», думайте о процессе в операционной системе. По сути, это экземпляр программы, работающей в системе.
Если запустить наше Electron-приложение и заглянуть в Диспетчер Задач в Windows, Мониторинг Активности в macOS или Системный Монитор в Linux, то можно увидеть процессы, связанные с приложением.
Все они работают параллельно, однако память и ресурсы, выделенные под каждый из них, изолированы от других процессов.
Допустим, мы хотим написать цикл в процессе рендеринга:
Этот код никак не повлияет на основной процесс.
Основной процесс
Этот процесс контролирует происходящее в приложении. В него встроен полноценный Node.js API. Из него создаются процессы рендеринга и открываются диалоговые окна. Также он отвечает за разное взаимодействие с операционной системой, запускает и закрывает приложение.
Имейте в виду, что основной процесс может быть только один.
Процесс рендеринга
Этот процесс представляет собой окно браузера в вашем приложении. В отличие от основного процесса, процессов рендеринга может быть несколько и каждый из них будет независим от остальных. За счёт этого ошибка в одном из них никак не повлияет на другие. Скажем за это спасибо многопроцессорной архитектуре Chromium. Также эти окна можно спрятать или изменить, так как они работают как HTML-файлы.
Но в Electron у нас также есть доступ к Node.js API. Это значит, что мы можем открывать диалоговые окна и взаимодействовать с операционной системой прочими способами.
Представить происходящее можно следующим образом:
Остаётся один вопрос. Можно ли как-нибудь связать эти процессы?
Эти процессы выполняются одновременно и независимо. Однако им всё равно нужно как-то взаимодействовать. Особенно учитывая то, что они отвечают за разные задачи.
Специально для таких целей существует межпроцессное взаимодействие (IPC). Его можно использовать для передачи сообщений между основным процессом и процессами рендеринга.
Вот мы и разобрались с основами процессов для создания Electron-приложения. Возвращаемся к коду!
Добавим индивидуальности
Помните, что вы всегда можете ввести npm start в терминале, чтобы запустить приложение и посмотреть на внесённые изменения.
Пора идти дальше и добавить в наше приложение функциональность.
Добавляем функциональность
Мы хотим, чтобы при нажатии клавиши на клавиатуре проигрывался соответствующий звук. Чтобы реагировать на пользовательский ввод, мы должны определить элемент, который будет перехватывать нажатия клавиш и затем активировать нужное действие.
Для этого мы создадим элементы audio со своим id для каждой клавиши. Затем напишем switch-конструкцию, чтобы понять, какая клавиша была нажата. После этого воспроизведём звук, привязанный к этой клавише. Если это звучит сложно — не беспокойтесь, мы разберёмся со всем пошагово.
Скачайте этот архив с нужными нам аудиофайлами. Пора встраивать аудио в наше приложение.
Откройте index.html и внутри создайте новый элемент
Затем внутри этого
В итоге код должен выглядеть так:
Теперь index.html имеет примерно такой вид:
Отлично! Теперь нам не хватает только JavaScript-кода.
Проект теперь должен иметь такой вид:
Отлично! Теперь, когда уже почти всё готово, наступает момент истины.
Откроем functions.js и добавим туда следующий код:
Откройте консоль, убедитесь, что вы находитесь в директории проекта и введите npm start для запуска приложения.
Сделайте звук погромче и нажмите клавишу «А» на клавиатуре.
В анонимной функции мы используем switch-выражение, которое выясняет Unicode-значение нажатой клавиши. Если это значение правильное, то воспроизводится звук. В противном случае в консоль выводится сообщение: «Клавиша не обнаружена!».
Как вы могли заметить, у нас есть файлы для клавиш от A до Z и от 0 до 9. Поэтому давайте используем и их, чтобы «А» было не так одиноко.
Код для каждой клавиши можно найти здесь. Но вы по-прежнему можете просто скопировать:
Прим. перев. Как вы, вероятно, заметили, такая switch-case конструкция выглядит довольно громоздко. А как вы бы оптимизировали этот участок кода? Делитесь своими вариантами в комментариях.
Вот мы и закончили наше приложение! Поздравляем!
Основная функциональность в приложении присутствует, но его ещё можно доработать.
Дополняем приложение
Да, у нас всё работает, но всё равно то тут, то там чего-то не хватает. Например, в index.html вы можете изменить заголовок приложения и содержимое основного окна. Кроме того, у нас нет никакого дизайна, нет красивых цветов и нет картинок с котиками. Включите воображение и попробуйте улучшить внешний вид приложения.
Код тоже не верх совершенства. У нас куча одинакового кода, который можно оптимизировать и улучшить. В итоге код будет занимать меньше места, и глазам будет не так больно. Помните: повторяющийся код — это плохо.
Тестируем, тестируем и ещё раз тестируем
Хорошее ПО должно быть тщательно протестировано. Попробуйте нажать каждую клавишу, чтобы увидеть, что произойдёт. В лучшем случае вы услышите звук для каждой клавиши, указанной в коде. Но что если вы нажмёте много клавиш подряд так быстро, как только можете? А что насчёт клавиш вроде Home и NumLock, для которых у нас нет звука?
Если вы свернёте приложение и нажмёте клавишу, вы услышите звук? А если окно приложения неактивно, и вы нажмёте клавишу, то что-нибудь произойдёт?
К сожалению, ответ — нет.
Так происходит из-за архитектуры, на которой построен Electron. Вы можете регистрировать нажатия клавиш внутри приложения как в C#, но не можете этого делать за его пределами. Это выходит за рамки привычных Electron-приложений.
Пройдитесь по коду строка за строкой и попробуйте сделать его нерабочим. Посмотрите, что произойдёт и какие ошибки выбросит Electron. Это упражнение поможет вам разобраться в отладке. Если вы знаете слабые места своего приложения, то вы знаете, как их исправить и сделать приложение лучше.
В файле functions.js было использовано устаревшее событие. Сможете его найти? Когда найдёте, подумайте, как его заменить без изменения функциональности приложения.
Использование устаревшего кода — плохая практика. Это может привести к серьёзным багам, о существовании которых вы могли даже не подозревать. Следите за документацией языка, чтобы знать, какие произошли изменения. Всегда будьте в курсе последних событий.
Руководство по созданию настольного приложения в Electron
Если вы занимаетесь веб-разработками, то, вероятно, наслышаны об Electron. Для тех же, кто не в курсе, скажу, что это достаточно противоречивый фреймворк для создания приложений, совместимых с Windows, macOS и Linux, на основе веб-технологий и единой базы кода. Несмотря на то, что его приложения могут уступать нативным в скорости и легковесности, Electron позволяет веб-разработчикам развертывать их на 3 главных PC платформах, а, значит, экономит наше время и деньги. Фактически ряд широко распространенных настольных приложений, включая Visual Studio Code, Slack и Discord, созданы с помощью Electron.
В данном руководстве мы создадим простое приложение Electron. Предварительно вам необходимо ознакомиться с Node.js, лежащей в основе рассматриваемого фреймворка. Помимо этого не обойтись без первоначальных знаний о библиотеке Express. И в качестве бонуса используем TypeScript вместо JavaScript, после чего вы, вряд ли, захотите вернуться к JS.
При желании можете обратиться к моему репозиторию за более подробным материалом о приложении Electron с фронтендом Angular.
Введение
По сути, приложения Electron работают по той же фронтенд/бэкенд модели, что и большинство веб-приложений. Отличие же в том, что фронтенд-часть выполняется не в браузере, а в своем отдельном окне, при этом бэкенд-компонент является приложением Node, выполняющимся локально, а не на сервере.
Процесс создания приложения можно разбить на несколько основных этапов:
О безопасности: внашем примере для обеспечения взаимодействия фронтенда и бэкенда послужит сервер Express, что позволит нам оптимизировать процесс разработки и легко перенести в Electron уже имеющиеся у вас веб-приложения. Однако в производственной среде с этой целью всегда применяется Electron IPC.
1. Настройка среды
Сначала убедитесь, что на вашем компьютере установлен Node.
Примечание: по желанию на данном этапе вы также можете настроить систему контроля версий Git. Сделав это, убедитесь, что она игнорирует папки /dist и /build , поскольку в них будет находиться транслированный код и скомпилированные исполняемые файлы.
Установка зависимостей
Для установки необходимых зависимостей выполните из корневого каталога проекта следующие команды:
2. Настройка TypeScript
В папке проекта создайте файл с именем tsconfig.json и скопируйте в него следующее:
Опция include информирует транспилятор, где искать файлы с кодом TS, а опция exclude явно указывает, какие компоненты исключить.
Исходные директории
Преобразования package.json
Эти скрипты определяют команды, которые мы можем выполнять в проекте. Команда transpile транспилирует код TypeScript в JavaScript.
watch осуществляет постоянный контроль кода TypeScript и в случае внесения изменений автоматически выполняет его напрямую без предварительной транспиляции в JavaScript. Во время тестирования данная процедура может оказаться очень полезной.
3. Создание бэкенда
Обычный бэкенд Node содержит лишь код для обработки HTTP-запросов от клиента. Помимо этого, бэкенд Electron содержит еще и код для обработки самого процесса Electron.
Давайте разберем этот код. Сначала мы импортируем необходимые модули:
Далее устанавливаем переменную const PORT для настройки порта, который будет прослушиваться сервером. Это может быть любое произвольное число. Однако советую выбирать числа в диапазоне 49152–65535 во избежание конфликтов с зарезервированными или часто используемыми портами.
До настоящего момента наш код сообщал Electron, что и как нужно делать с окном приложения, но ничего не говорил про реализацию работы самого приложения. Этой цели послужат строки с 30 по 50. С помощью app.on они определяют 3 функции обратных вызовов, которые срабатывают при определенных событиях.
Поскольку вы знакомы с Node и Express, мы не будем рассматривать код после 52 строки.
Итак, у нас есть необходимый код для запуска приложения Electron и сервера Express в фоновом режиме. Но нам по-прежнему требуется фронтенд для взаимодействия с сервером.
4. Создание фронтенда
Здесь нет ничего особенного — обычная HTML-страница с простым стилем для взаимодействия с бэкендом. Отметим лишь, что любой HTTP-запрос, осуществляемый фронтендом, должен иметь правильный номер порта.
5. Тестирование приложения
На этом этапе приложение готово для сборки. Приступайте к генерации исполняемого файла, только убедившись, что все работает, как нужно.
Протестируйте приложение и по мере необходимости вносите любые изменения. Не забывайте обновлять окно браузера после корректировки фронтенд-кода.
Убедившись, что все работает, переходите к следующему разделу.
6. Сборка приложения
Заключение
Надеюсь, что благодаря этому руководству вы научились разрабатывать настольные приложения в Electron.
Создание настольных приложений с помощью Electron. Руководство для начинающих
Поверите ли вы мне, если я скажу, что настольные приложения Slack, VSCode, Atom, Skype, Discord и Whatsapp, которыми вы сегодня пользуетесь, были написаны с использованием HTML, CSS и JavaScript? Вероятно, нет. Потому что обычно эти языки мы используем только для разработки веб-сайтов.
Но как быть в том случае, если в настольном приложении применяется браузер в виде графического интерфейса (то, что видит пользователь)? Тогда мы могли бы применять эти языки для визуализации пользовательского интерфейса приложения. Именно этот вариант и действует в указанных выше приложениях. Эти приложения используют скрытый браузер для визуализации пользовательского интерфейса, поэтому для рисования можно использовать HTML и CSS, а для интерактивности — JavaScript.
Хотя проектирование графического интерфейса с использованием HTML, CSS и JavaScript кажется простым, вам все равно нужен мост между собственными системными API и браузером (в приложении) для ввода-вывода (файловая система), доступа к сети, оборудованию и другим компонентам системы. Без доступа к системным ресурсам наше настольное приложение было бы просто веб-сайтом.
В приложении мы могли бы использовать Node.js, чтобы он действовал как мост между системными ресурсами и браузером. Если код JavaScript, запущенный в браузере, нуждается в доступе к некоторым файлам из системы, он может сделать такой запрос Node.js. Поскольку Node.js может получить доступ к общесистемным ресурсам без каких-либо ограничений, он идеально подходит для работы с бэкендом приложения, без всяких доработок.
Теоретически это похоже на идеальный метод. Но когда дело доходит до реального создания приложения, необходимы познания о разработке собственных настольных приложений, об интеграции с браузером, API-интерфейсах браузера, интеграции Node.js и о многих других вещах. Но не стоит пугаться, ведь у нас есть Electron.
Electron — это инструмент для создания кросс-платформенных настольных приложений с веб-технологиями. Electron использует Node.js для бэкенда приложения и браузер Chromium для фронтенда. Мы можем написать графический интерфейс приложения с помощью HTML, CSS и JavaScript. Electron обеспечивает интеграцию между JavaScript, работающим в браузере, и JavaScript, работающим в Node.js.
На самом деле, указанные выше приложения созданы с помощью Electron. Он имеет огромное сообщество, множество сторонних модулей, большинство компаний полагаются на него в своих настольных приложениях. Вот список таких приложений. В нем вы также можете найти Twitch, Zeplin и WebTorrent.
💡 Подобно Electron, для создания настольных приложений вы также можете применять NW.js. Я лично не считаю, что с NW.js комфортно работать. А чтобы узнать различия между этими двумя инструментами, вы можете ознакомиться с этой документацией.
Архитектура Electron
BrowserWindow — это просто интерфейс высокого уровня для отображения и управления веб-страницей, но сам он не может отображать веб-страницы. Интерфейс webContent — это низкоуровневый API, который отвечает за визуализацию и управление веб-страницей с помощью процесса визуализации Chromium.
Процесс Main против Renderer
Совершенно очевидно, что процесс main управляет состоянием приложения, а процессы renderer управляют пользовательским интерфейсом приложения. Хотя, есть несколько элементов, к которым процесс renderer не может иметь доступ.
💡 Причина, по которой Electron не предоставляет доступ к API-интерфейсам Node.js из процессов renderer по умолчанию, заключается в том, что вредоносный сторонний код JavaScript, например сторонняя библиотека, может получить доступ к системе пользователя, вызвав API-интерфейсы Node. Поэтому будьте осторожны.
Взаимодействие между процессами
Теперь, когда мы выяснили, что процесс main предназначен для координации работы приложения и связи между системными ресурсами и приложением, а процесс renderer для визуализации пользовательского интерфейса приложения, осталось выяснить, как мы можем справиться с ограничениями.
💡 Эти коммуникации могут происходить синхронно или асинхронно в зависимости от методов модуля.
Фоновые задания
Для выполнения фоновых и ресурсоемких задач некоторые специалисты могут предложить окна frameless transparent, которые пользователи не видят. Однако, когда есть способы получше, такик уловки следует избегать.
💡 Хотя мы можем получить доступ ко всем API-интерфейсам Node.js внутри веб-воркера, получить доступ к собственным API-интерфейсам Electron невозможно. Для получения дополнительной информации о многопоточности в Electron прочтите эту документацию.
Общее описание
Все, что мы обсуждали до сих пор — это просто обзор архитектуры Electron. А для тех, кто хочет знать больше, можно почитать вот эту документацию. Подведем итог проведенному обсуждению с помощью упрощенной диаграммы.
Создание приложения с помощью Electron
Есть еще один важный момент, который нельзя забывать. Точкой входа в приложение Electron является файл JavaScript. Этот файл JavaScript выполняется внутри процесса main и открывает окна приложений. Итак, создадим внутри проекта файл main.js :
💡 Переменная process поступает из Node.js, поскольку процесс main всегда имеет доступ к API-интерфейсам Node.js. Следовательно process.platform дает название базовой платформы (ядра или ОС), на которой выполняется Node.js.
Событие activate специфично для macOS и запускается при нажатии значка приложения на док-станции (и в других местах). Поскольку закрытие всех окон в macOS не приводит к закрытию приложения (процесс main ), нам нужно будет открыть окно (если ни одно из них не открыто) при повторной активации приложения.