Создание Вашего первого приложения
Это 2 часть руководства по Electron.
Цели обучения
В этой части руководства вы узнаете, как настроить проект Electron и написать базовое небольшое приложение. К концу этого раздела вы научитесь запускать из терминала работающее приложение Electron в режиме разработки.
Настройка проекта
Если вы работаете на компьютере с ОС Windows, пожалуйста, не используйте Windows Subsystem for Linux (WSL) при изучении данного руководства, поскольку при попытке запуска приложения вы столкнетесь с проблемами.
Инициализация npm проекта
Для создания приложений Electron используется npm, а в качестве отправной точки используется файл package.json. Для начала создайте папку и инициализируйте в ней пакет npm с помощью npm init.
- npm
- Yarn
mkdir my-electron-app && cd my-electron-app
npm init
mkdir my-electron-app && cd my-electron-app
yarn init
Эта команда предложит вам настроить несколько полей в файле package.json. В этом руководстве стоит придерживаться следующего:
- точкой входа должен быть файл
main.js(этот файл будет создан позже). - поля author, license, и description могут быть любыми значениями, но они будут необходимы для упаковки приложения позже.
node_modules folderElectron's packaging toolchain requires the node_modules folder to be physically on disk in the way that npm installs Node dependencies. By default, Yarn Berry and pnpm both use alternative installation strategies.
Therefore, you must set nodeLinker: node-modules in Yarn or nodeLinker: hoisted in pnpm if you are using those package managers.
Затем установите Electron в devDependencies своего приложения, представляющий собой список внешних зависимостей пакетов, предназначенных только для разработки и не требующихся в продакшене.
Это может показаться нелогичным, поскольку в продакшене используется API Electron. Under the hood, Electron's JavaScript API binds to a binary that contains its implementations. The packaging step for Electron handles the bundling of this binary, eliminating the need to specify it as a production dependency.
- npm
- Yarn
npm install electron --save-dev
yarn add electron --dev
In order to correctly install Electron, you need to ensure that its postinstall lifecycle script is able to run. This means avoiding the --ignore-scripts flag on npm and allowlisting electron to run build scripts on other package managers.
This is likely to change in a future version of Electron. See electron/rfcs#22 for more details.
После инициализации пакета и установки Electron ваш файл package.json должен выглядеть примерно так. Кроме того, теперь у вас должны появиться папка node_modules, содержащая исполняемый файл Electron, а также файл фиксации package-lock.json, в котором указаны точные версии зависимостей для установки.
{
"name":"my-electron-app",
"version":"1.0.0",
"description":"Hello World!",
"main":"main.js",
"scripts":{
"test":"echo \"Error: no test specified\" && exit 1"
},
"author":"Jane Doe",
"license":"MIT",
"devDependencies":{
"electron":"23.1.3"
}
}
Если установка Electron напрямую не удается, обратитесь к документации по Расширенной установке для получения рекомендаций по зеркалам загрузки, прокси и способам устранения неполадок.
Добавление .gitignore
Файл .gitignore указывает, какие файлы и каталоги не нужно отслеживать посредством Git. Копию шаблона GitHub's Node.js gitignore следует поместить в корневую папку проекта, чтобы избежать коммитов папки node_modules.
Запуск приложения Electron
Read Electron's process model documentation to better understand how Electron's multiple processes work together.
Скрипт main, определенный в package.json, является точкой входа в любое приложение Electron. Этот скрипт управляет основным процессом (main), который работает в среде Node.js и обеспечивает управление жизненным циклом приложения, отображением нативных интерфейсов, выполнением привилегированных операций и управлением процессами рендеринга (подробнее о них мы поговорим позже).
Перед тем как создать свое первое приложение Electron, сначала реализуем простейший сценарий, чтобы убедиться, что точка входа в основной процесс настроена правильно. Создайте в корневой папке проекта файл main.js с одной строкой кода:
console.log('Привет из Electron 👋')
Because Electron's main process is a Node.js runtime, you can execute arbitrary Node.js code with the electron command (you can even use it as a REPL). Чтобы запустить этот код, добавьте electron . к команде start в поле scripts в package.json. Эта команда укажет исполняемому модулю Electron искать основной скрипт в текущем каталоге и запускать его в режиме разработки (dev).
{
"name":"my-electron-app",
"version":"1.0.0",
"description":"Hello World!",
"main":"main.js",
"scripts":{
"start":"electron .",
"test":"echo \"Error: no test specified\" && exit 1"
},
"author":"Jane Doe",
"license":"MIT",
"devDependencies":{
"electron":"23.1.3"
}
}
- npm
- Yarn
npm run start
yarn run start
В терминале должно появиться сообщение Привет из Electron 👋. Поздравляем, вы выполнили первую строку кода в Electron! Далее вы научитесь создавать пользовательские интерфейсы с помощью HTML и загружать их в нативном окне ОС.
Загрузка веб-страницы внутри BrowserWindow
В Electron каждое окно выводит веб-страницу, которая может быть загружена либо из локального HTML-файла, либо с удаленного веб-адреса. В данном примере мы будем загружать локальный файл. Начните с создания базовой веб-страницы в файле index.html в корневой папке вашего проекта:
<!DOCTYPEhtml>
<html>
<head>
<metacharset="UTF-8"/>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>Привет из Electron renderer!</title>
</head>
<body>
<h1>Привет из Electron renderer!</h1>
<p>👋</p>
</body>
</html>
Now that you have a web page, you can load it into an Electron BrowserWindow. Замените содержимое файла main.js следующим кодом. Каждый блок мы рассмотрим отдельно.
const{ app,BrowserWindow}=require('electron')
constcreateWindow=()=>{
const win =newBrowserWindow({
width:800,
height:600
})
win.loadFile('index.html')
}
app.whenReady().then(()=>{
createWindow()
})
Импорт модулей
const{ app,BrowserWindow}=require('electron')
В первой строке мы импортируем два модуля Electron с использованием стандарта CommonJS:
- app, which controls your application's event lifecycle.
- BrowserWindow, which creates and manages app windows.
Module capitalization conventions
Возможно, вы заметили разницу в написании заглавных между именами модулей app и BrowserWindow. Electron следует типичным для JavaScript соглашениям, где модули в стиле именования PascalCase являются объектами-конструкторами (например: BrowserWindow, Tray, Notification), а модули camelCase - нет (например: app, ipcRenderer, webContents).
Typed import aliases
For better type checking when writing TypeScript code, you can choose to import main process modules from electron/main.
const{ app,BrowserWindow}=require('electron')
For more information, see the Process Model docs.
ECMAScript modules (i.e. using import to load a module) are supported in Electron as of Electron 28. You can find more information about the state of ESM in Electron and how to use them in our app in our ESM guide.
Написание многоразовой функции для создания экземпляров окон
Функция createWindow() загружает веб-страницу в новый экземпляр BrowserWindow:
constcreateWindow=()=>{
const win =newBrowserWindow({
width:800,
height:600
})
win.loadFile('index.html')
}
Вызов функции, когда приложение готово к работе
app.whenReady().then(()=>{
createWindow()
})
Многие модули ядра Electron являются генераторами событий (эмиттерами) Node.js, которые соблюдают асинхронную событийно-ориентированную архитектуру Node. Модуль app является одним из таких генераторов.
In Electron, BrowserWindows 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 and calling createWindow() once its promise is fulfilled.
В большинстве случаев для прослушивания событий Node.js используется функция .on эмиттера.
+ app.on('ready', () => {
- app.whenReady().then(() => {
createWindow()
})
Однако Electron предоставляет app.whenReady() в качестве хелпера специально для события ready, чтобы избежать нюансов, связанных, в частности, с непосредственным прослушиванием этого события. Подробнее: electron/electron#21972.
На этом этапе команда start вашего приложения Electron должна успешно открыть окно, в котором отображается выбранная веб-страница!
Каждая веб-страница, отображаемая вашим приложением в окне, будет выполняться в отдельном процессе, называемом процессом отображения (или просто renderer). Процессы отображения имеют доступ к тем же JavaScript API и инструментарию, которые вы используете для обычной front-end разработки, например, к webpack для сборки и минификации кода или к React для создания пользовательских интерфейсов.
Управление жизненным циклом окон вашего приложения
Application windows behave differently on each operating system. Rather than enforce these conventions by default, Electron gives you the choice to implement them in your app code if you wish to follow them. You can implement basic window conventions by listening for events emitted by the app and BrowserWindow modules.
Checking against Node's process.platform variable can help you to run code conditionally on certain platforms. Note that there are only three possible platforms that Electron can run in: win32 (Windows), linux (Linux), and darwin (macOS).
Quit the app when all windows are closed (Windows & Linux)
On Windows and Linux, closing all windows will generally quit an application entirely. To implement this pattern in your Electron app, listen for the app module's window-all-closed event, and call app.quit() to exit your app if the user is not on macOS.
app.on('window-all-closed',()=>{
if(process.platform!=='darwin') app.quit()
})
Open a window if none are open (macOS)
In contrast, macOS apps generally continue running even without any windows open. 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 BrowserWindows 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 only listening for activate events inside your existing whenReady() callback.
app.whenReady().then(()=>{
createWindow()
app.on('activate',()=>{
if(BrowserWindow.getAllWindows().length===0)createWindow()
})
})
Окончательный вариант кода запуска
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<meta
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
<title>Hello from Electron renderer!</title>
</head>
<body>
<h1>Hello from Electron renderer!</h1>
<p>👋</p>
<pid="info"></p>
</body>
<scriptsrc="./renderer.js"></script>
</html>