Electron таргет

Многопроцессная модель Electron и влияние на сборку

Electron-приложение состоит из двух ключевых контекстов выполнения: main process и renderer process. Каждый из них требует отдельного подхода к сборке, поскольку отличается средой исполнения:

  • Main process работает в Node.js-окружении
  • Renderer process работает в Chromium-окружении с доступом к DOM
  • Preload-скрипты выполняются в изолированном контексте с ограниченным доступом к Node.js API

Parcel учитывает эту архитектуру через систему targets, позволяющую описывать несколько выходных сборок в рамках одного проекта.


Система targets в Parcel для Electron

Parcel v2 вводит концепцию мульти-таргетной сборки, где каждый target описывает отдельный бандл с собственными параметрами окружения.

Для Electron используются специализированные типы таргетов:

  • electron-main
  • electron-renderer

Каждый из них задаёт корректные условия трансформации кода, включая:

  • режим модулей (CommonJS / ESM)
  • доступность Node.js API
  • оптимизации под Chromium
  • корректную обработку __dirname, process, require

Пример конфигурации targets в package.json

{
  "name": "electron-app",
  "main": "dist/main.js",
  "targets": {
    "main": {
      "context": "electron-main",
      "distDir": "dist/main"
    },
    "renderer": {
      "context": "electron-renderer",
      "distDir": "dist/renderer"
    }
  }
}

Parcel автоматически разделяет граф зависимостей на две независимые сборки, избегая смешивания Node и browser API.


Electron Main Process в Parcel

Main process представляет собой точку входа приложения, отвечающую за:

  • создание окон (BrowserWindow)
  • управление жизненным циклом приложения
  • взаимодействие с файловой системой
  • IPC между процессами

Parcel при сборке electron-main:

  • сохраняет Node.js-совместимость
  • не применяет DOM-трансформации
  • не полифиллит браузерные API
  • корректно обрабатывает require() и динамические импорты

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

  • поддержка __dirname без разрушения контекста
  • сохранение синхронных Node API
  • исключение Chromium-специфичных оптимизаций
  • возможность external dependencies (например, electron пакет)

Electron Renderer Process

Renderer-таргет ориентирован на UI-часть приложения, где выполняется React, Vue, Svelte или vanilla DOM.

Parcel для electron-renderer:

  • использует browser environment
  • применяет tree-shaking и minification
  • поддерживает HMR (Hot Module Replacement)
  • обрабатывает ассеты (CSS, изображения, fonts)

Особенности renderer-сборки

  • поддержка ESM и динамического импорта
  • оптимизация DOM-бандла
  • инлайнинг ассетов по правилам Parcel
  • разделение чанков для ленивой загрузки

Preload-скрипты и их интеграция

Preload-слой является мостом между main и renderer процессами. Он выполняется в изолированной среде с доступом к ограниченному Node API.

Parcel не выделяет отдельный тип таргета, но позволяет описывать preload как самостоятельную точку входа:

{
  "targets": {
    "preload": {
      "context": "electron-main",
      "distDir": "dist/preload"
    }
  }
}

Роль preload-слоя

  • безопасное экспонирование API через contextBridge
  • ограничение доступа renderer к Node.js
  • проксирование IPC вызовов

Разделение входных точек проекта

Типичная структура Electron-проекта с Parcel:

src/
  main/
    index.js
  renderer/
    index.html
    app.js
  preload/
    index.js

Parcel автоматически строит граф зависимостей отдельно для каждой точки входа, если они определены через targets.


Dev-режим и HMR в Electron

Parcel обеспечивает горячую перезагрузку для renderer-части и частично для main процесса.

Renderer HMR

  • мгновенная замена модулей без перезапуска окна
  • сохранение состояния UI (в зависимости от фреймворка)
  • пересборка только изменённых модулей

Main process reload

Main процесс требует перезапуска Electron при изменениях. Обычно используется связка:

  • Parcel watcher
  • автоматический restart Electron

Принцип работы:

  • Parcel пересобирает main bundle
  • процесс Electron перезапускается внешним watcher-скриптом

Интеграция с Electron runtime

Parcel не управляет жизненным циклом Electron, но обеспечивает корректную выдачу артефактов:

  • main bundle указывается в package.json → main
  • renderer загружается через loadFile или loadURL
  • preload подключается через webPreferences.preload

Пример подключения в main процессе

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

function createWindow() {
  const win = new BrowserWindow({
    webPreferences: {
      preload: __dirname + '/. ./preload/index.js',
      contextIsolation: true
    }
  });

  win.loadFile(__dirname + '/. ./renderer/index.html');
}

app.whenReady().then(createWindow);

Production-сборка Electron-приложения

Parcel отвечает только за бандлинг, но не за упаковку приложения. В production пайплайне обычно разделяются этапы:

  1. Parcel build для всех targets
  2. Упаковка через Electron Builder или Electron Forge
  3. Подпись и дистрибуция

Parcel обеспечивает:

  • минимизацию renderer-кода
  • оптимизацию ассетов
  • дедупликацию зависимостей
  • корректное разделение main/renderer/preload

Особенности оптимизации бандла

Parcel в Electron-режиме учитывает специфику окружения:

  • исключение браузерных полифиллов в main
  • сохранение native Node modules
  • корректная обработка electron как external dependency
  • разделение vendor chunks для renderer

Работа с нативными модулями

Electron часто использует native addons (.node файлы). Parcel:

  • не транспилирует binary modules
  • сохраняет пути загрузки
  • требует корректного external mapping

Типичная проблема — попытка бандлинга нативного модуля в renderer, что приводит к runtime error. Решение — объявление external зависимостей.


Типичные архитектурные ошибки при использовании Parcel с Electron

Смешивание контекстов

Попытка использовать DOM API в main процессе или Node API в renderer приводит к ошибкам выполнения.

Неправильная настройка targets

Отсутствие разделения electron-main и electron-renderer приводит к:

  • утечке Node polyfills в UI
  • увеличению размера бандла
  • нестабильности HMR

Игнорирование preload-слоя

Прямой доступ renderer к Node.js API нарушает модель безопасности Electron.


Модель зависимости между процессами

Parcel формирует три независимых графа:

  • main graph → Node environment
  • renderer graph → browser environment
  • preload graph → hybrid isolated environment

Связь между ними осуществляется только через Electron IPC, а не через импорт модулей.


IPC как связующее звено

Parcel не вмешивается в IPC-модель, но поддерживает её структуру через корректный бандлинг:

  • ipcMain в main
  • ipcRenderer в renderer
  • безопасные мосты через preload

Асинхронная загрузка модулей в renderer

Parcel поддерживает code splitting, что особенно важно в Electron UI:

  • lazy-loaded окна
  • динамические панели
  • отложенные модули аналитики

Каждый chunk загружается Chromium-движком независимо.


Кеширование и ускорение сборки

Parcel применяет:

  • content hashing
  • persistent cache
  • инкрементальную пересборку графа

В Electron-проектах это особенно заметно при больших renderer-приложениях с UI-фреймворками.


Изоляция окружений как базовый принцип

Ключевая модель Parcel в Electron:

  • main = Node
  • renderer = Browser
  • preload = безопасный мост

Нарушение границ приводит к деградации архитектуры и усложнению сопровождения кода.