Основные концепции Electron

Electron по сути представляет собой многопроцессный фреймворк для настольных приложений, который объединяетChromium (слой рендеринга)иNode.js (системный слой)и благодаря независимой процессной модели обеспечивает отображение UI, управление логикой и безопасную коммуникацию.

Ниже представлена основная архитектура Electron, показывающая взаимосвязь между главным процессом, процессом рендеринга, IPC-коммуникацией и Preload.

Главный процесс (A):

  • Работает на Node.js, управляет окнами и взаимодействует с системой.
  • Используйте BrowserWindow для создания процесса рендеринга.

Процесс рендеринга (B):

  • Каждое окно независимо запускает HTML/CSS/JS для отображения интерфейса.

Preload-скрипт (B2):

  • Выполняется до загрузки процесса рендеринга, соединяя главный процесс и слой веб-страницы.
  • Безопасно предоставлять API через contextBridge.

IPC-взаимодействие (пунктирные стрелки):

  • Главный процесс и процесс рендеринга обмениваются данными в обоих направлениях через ipcMain и ipcRenderer.

Операционная система (C):

  • Главный процесс может получать доступ к системным функциям, таким как файлы, трей, уведомления и т. д.


Главный процесс

Главный процесс — это "командный центр" приложения Electron, работающий в среде Node.js.
Он отвечает за создание окон, управление жизненным циклом приложения, вызов системных API и взаимодействие с процессом рендеринга.
После запуска приложения система сначала запускает скрипт главного процесса (обычноmain.js)。

Обязанности главного процесса

  • Запуск и выход из приложения
  • Создание и уничтожение BrowserWindow (окон)
  • Регистрация меню, трея, глобальных сочетаний клавиш
  • Вызов функций операционной системы (файловая система, уведомления, диалоги)
  • Прослушивание событий, отправляемых процессом рендеринга

Жизненный цикл главного процесса

Жизненный цикл главного процесса совпадает с жизненным циклом приложения, начиная сappНачало модуля:

Пример

const { app, BrowserWindow } = require('electron');

app.whenReady().then(() => {
  const win = new BrowserWindow({ width: 800, height: 600 });
  win.loadFile('index.html');
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});
  • app.whenReady(): Срабатывает после завершения инициализации Electron.
  • window-all-closed: Срабатывает при закрытии всех окон.
  • app.quit(): Завершает работу всего приложения.
  • Распространённый особый случай в macOS: когда пользователь закрывает все окна, программа продолжает работать в фоновом режиме.

Подробно о модуле app

appМодуль, используемый для управления жизненным циклом всего приложения:

  • app.on('ready'): Срабатывает, когда инициализация Electron завершена.
  • app.quit(): Завершить приложение.
  • app.getPath('userData'): Получить системные пути.
  • app.setAppUserModelId(id): Установить идентификатор панели задач Windows.
  • app.isPackaged: Определить, упакована ли текущая сборка.

Управление окнами BrowserWindow

Главный процесс черезBrowserWindowСоздайте видимое окно:

Пример

const win = new BrowserWindow({
  width: 1024,
  height: 768,
  resizable: true,
  webPreferences: {
    preload: './preload.js',
    nodeIntegration: false
  }
});
  • width, height: Размер окна
  • resizable: Можно ли изменять его размер
  • webPreferences: Используется для настройки поведения процесса рендеринга

    • preload: Скрипт предзагрузки
    • nodeIntegration: Разрешать ли процессу рендеринга использовать Node.js

Нативные функции, такие как меню, трей, диалоговые окна и т. д.

Electron предоставляет несколько модулей для доступа к системным функциям:

  • Menu / MenuItem: Настраиваемая строка меню
  • Tray: Создание значка в системном трее
  • Dialog: Вызов системного диалога выбора файлов и диалога предупреждения
  • Notification: Нативные уведомления
  • shell: Открытие внешних ссылок или файлов, например:

    const { dialog } = require('electron');
    dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] });

Процесс рендеринга

Процесс рендеринга отвечает за отображение интерфейса и работает в среде Chromium.
каждыйBrowserWindowУ каждого есть независимый процесс рендеринга.

Особенности процесса рендеринга

  • Основан на Chromium, выполняет HTML/CSS/JS
  • По умолчаниюНе может напрямую обращаться к API Node.js(по соображениям безопасности)
  • Может использовать стеки веб-технологий: Vue, React, Svelte и т. д.
  • Каждое окно соответствует независимому потоку, и они не влияют друг на друга.

Несколько окон и несколько процессов рендеринга

Каждое окно Electron (BrowserWindow) запустит независимый процесс рендеринга:
Закрытие одного окна не влияет на другие окна, аналогично модели с несколькими вкладками в браузере.
Это делает приложение безопаснее и надёжнее при восстановлении после сбоев.

Загрузка и отображение веб-страниц

Содержимое процесса рендеринга загружается главным процессом:

win.loadFile('index.html');    // 加载本地页面
// 或者
win.loadURL('https://example.com'); // 加载远程网页

Ограничения в процессе рендеринга

  • По соображениям безопасности модули Node.js нельзя использовать напрямую (такие какfs、path)。
  • Не рекомендуется выполнять высоконагруженные вычисления в процессе рендеринга (это заморозит UI).
  • Для взаимодействия с системой требуется IPC-взаимодействие или API, предоставляемые через preload.

Межпроцессное взаимодействие (IPC)

Один из основных механизмов Electron — этосвязь между главным процессом и процессом рендеринга, называемаяIPC(межпроцессное взаимодействие)。

ipcMain и ipcRenderer

  • ipcMain: Используется в главном процессе для получения сообщений.
  • ipcRenderer: Используется в процессе рендеринга для отправки сообщений.

Пример односторонней связи:

Пример

// main.js
const { ipcMain } = require('electron');
ipcMain.on('ping', (event, arg) => {
  console.log(arg); // Вывод "hello from renderer"
});

// renderer.js
const { ipcRenderer } = require('electron');
ipcRenderer.send('ping', 'hello from renderer');

Пример двусторонней связи (главный процесс отправляет данные обратно):

ipcMain.on('getVersion', (event) => {
  event.reply('getVersionResponse', app.getVersion());
});

Сторона рендерера получает:

ipcRenderer.on('getVersionResponse', (event, version) => {
  console.log(version);
});

Шаблон invoke/handle (рекомендуемый подход)

Electron предоставляет более лаконичный способ для асинхронных запросов:

Главный процесс:

ipcMain.handle('get-app-path', () => app.getPath('userData'));

Процесс рендерера:

const result = await ipcRenderer.invoke('get-app-path');
console.log(result);

Этот подход похож наfetchЗапросы, избегая множественных слоёв обратных вызовов.

Лучшие практики передачи сообщений

  • ИспользованиеЯвное имя канала(например,"user:getData")。
  • Избегайте передачи сложных объектов (рекомендуется JSON).
  • Данные из процесса рендеринга должны проверяться на источник и тип.
  • Постарайтесь использоватьinvoke/handleРеализуйте структурированное взаимодействие.

Preload (скрипты предзагрузки)

Скрипт preload выполняется до создания процесса рендеринга, между главным процессом и веб-страницей.
Его роль — «связать» возможности Node.js со страницей рендеринга.

Роль и значение preload

  • Может получать доступ к API Node.js (благодаря изолированному контексту)
  • Может безопасно предоставлять небольшое количество API странице рендеринга
  • Обычно используется для чтения/записи файлов, получения системных путей, передачи информации о приложении и т. д.
// preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  getAppVersion: () => ipcRenderer.invoke('getVersion')
});

Процесс рендеринга использует:

// index.html
<script>
  window.electronAPI.getAppVersion().then(v => {
    console.log('App version:', v);
  });
</script>

contextBridge: безопасное взаимодействие

contextBridge— это безопасный API, предоставляемый Electron, используемый для:

  • Предоставлять только необходимые функции (механизм белого списка)
  • Предотвращать доступ вредоносных веб-страниц к среде Node.js
  • ВcontextIsolation: trueВсё ещё можно безопасно взаимодействовать в этом режиме

Использование в режиме песочницы

Если песочница включена (sandbox: true), процесс рендеринга полностью не может использовать Node.js.
В этот момент preload — единственный мост, отвечающий за:

  • Получение вызовов со стороны рендерера
  • Передача в главный процесс через IPC
  • Возврат результатов на сторону веб-страницы

Итог

Модуль Функция Среда выполнения
Главный процесс (Main) Управление жизненным циклом приложения, окнами, системными интерфейсами Node.js
Процесс рендеринга Отображение UI, выполнение логики фронтенда Chromium
IPC Реализация связи между главным процессом и процессом рендеринга Двунаправленный канал
Preload Безопасное связывание Node и Web промежуточный слой

Понимание в одном предложении:
Главный процесс — это как "диспетчерская", процесс рендеринга — как "сотрудники каждого окна",
IPC — это «рация», а Preload — это «фильтрованный защищённый канал».

Другие расширения