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

В экосистеме Quasar Framework ключевым элементом является взаимодействие между главным процессом (main process) и рендер-процессом (renderer process), что унаследовано от архитектуры Electron при разработке настольных приложений. Понимание этой структуры критично для эффективной организации кода и управления жизненным циклом приложений.


Главный процесс (Main Process)

Главный процесс — это основной поток приложения, который запускается первым. Он отвечает за:

  • Создание окон приложения (BrowserWindow);
  • Управление жизненным циклом приложения;
  • Обработку событий на уровне системы (например, события закрытия окна, изменения состояния активности);
  • Настройку системных API (файловая система, нотификации, доступ к аппаратным ресурсам);
  • Организацию взаимодействия с рендер-процессами через IPC (ipcMain).

Главный процесс не отвечает за визуальное отображение. Любой рендеринг интерфейса происходит исключительно в рендер-процессе. Код главного процесса обычно находится в файле src-electron/main-process/index.js (или main.js в стандартной конфигурации Quasar Electron).

Пример создания окна в главном процессе:

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

function createMainWindow() {
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: `${__dirname}/preload.js`
    }
  });

  win.loadURL('http://localhost:8080');
}

app.whenReady().then(createMainWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) createMainWindow();
});

Ключевые моменты главного процесса:

  • nodeIntegration: false и contextIsolation: true — повышают безопасность, предотвращая прямой доступ к Node API из рендер-процесса.
  • preload.js — точка для безопасного обмена данными между главным и рендер-процессами через contextBridge.

Рендер-процесс (Renderer Process)

Рендер-процесс создается для каждого окна приложения и отвечает за отображение интерфейса, обработку событий пользовательского ввода и выполнение фронтенд-логики. Он работает в изолированном окружении, напоминающем браузер, с доступом к DOM и Vue-компонентам.

В Quasar рендер-процесс чаще всего содержит Vue-приложение, используя Quasar UI-компоненты:

import { createApp } from 'vue';
import { Quasar } from 'quasar';
import App from './App.vue';
import quasarUserOptions from './quasar-user-options';

const app = createApp(App);
app.use(Quasar, quasarUserOptions);
app.mount('#app');

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

  • Полный доступ к DOM и Vue-компонентам Quasar;
  • Возможность обращаться к Node API через безопасные каналы (contextBridge, ipcRenderer);
  • Рендер-процессы могут быть множественными, каждый для своего окна;
  • Ошибки в рендер-процессе не останавливают главный процесс, что повышает устойчивость приложения.

Взаимодействие через IPC

Для обмена данными между главным и рендер-процессами используется IPC (Inter-Process Communication). В главном процессе подключается ipcMain, а в рендер-процессе — ipcRenderer.

Пример обмена сообщениями:

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

const { ipcMain } = require('electron');

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

Рендер-процесс:

const { ipcRenderer } = require('electron');

async function fetchAppPath() {
  const path = await ipcRenderer.invoke('get-app-path');
  console.log('User Data Path:', path);
}

fetchAppPath();

Рекомендации по безопасности:

  • Всегда использовать ipcMain.handle и ipcRenderer.invoke для асинхронных запросов;
  • Не разрешать рендер-процессу напрямую управлять системными ресурсами;
  • Использовать contextBridge.exposeInMainWorld для создания безопасных API.

Preload скрипт и безопасное API

Файл preload.js позволяет создать мост между рендером и главным процессом, не нарушая контекстную изоляцию:

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  getAppPath: () => ipcRenderer.invoke('get-app-path'),
});

Теперь во Vue-компонентах можно безопасно обращаться к этому API:

mounted() {
  window.electronAPI.getAppPath().then(path => {
    console.log('User Data Path:', path);
  });
}

Практические рекомендации

  1. Разделять бизнес-логику между процессами: все системные операции в главном процессе, интерфейс и визуальные эффекты — в рендер-процессе.
  2. Минимизировать количество прямых вызовов Node API из рендер-процесса для безопасности.
  3. Использовать Quasar CLI для конфигурации Electron-приложений: команда quasar dev -m electron запускает оба процесса корректно.
  4. Логировать ошибки отдельно: main и renderer могут иметь свои журналы, что облегчает отладку.

Главный и рендер-процессы формируют ядро архитектуры Quasar в контексте Electron, обеспечивая разделение ответственности, безопасность и стабильность приложения. Правильная организация обмена данными через IPC и использование безопасного preload API делает разработку масштабируемой и управляемой.