Electron

Из-за природы Electron создание приложений Electron в виде Flatpaks требует нескольких дополнительных шагов по сравнению с другими приложениями. К счастью, доступно несколько инструментов и ресурсов, которые значительно упрощают эту задачу.

В этом руководстве представлена информация о том, чем создание приложений Electron отличается от других приложений. Он также включает информацию об инструментах для создания приложений Electron и о том, как их использовать.

В руководстве рассматривается «файл манифеста <https://github.com/flathub/electron-sample-app/blob/master/flatpak/org.flathub.electron-sample-app.yml>`_ образца «Electron Приложение Flatpak <https://github.com/flathub/electron-sample-app>`_. Прежде чем начать, рекомендуется взглянуть на это в Интернете или загрузив приложение.

Сборка образца приложения

Хотя в этом нет строгой необходимости, вы можете попробовать создать и запустить образец приложения самостоятельно.

Чтобы настроить сборку, загрузите или клонируйте пример приложения с GitHub и перейдите в каталог /flatpak в терминале. Вы также должны установить базовое приложение Electron и расширение Node.js SDK:

$ flatpak install flathub org.electronjs.Electron2.BaseApp//23.08
$ flatpak install flathub org.freedesktop.Sdk.Extension.node18//23.08

Затем вы можете запустить сборку:

$ flatpak-builder build org.flathub.electron-sample-app.yml --install --force-clean --user

Наконец, приложение можно запустить с:

$ flatpak run org.flathub.electron-sample-app

Базовая конфигурация

В первой части манифеста демонстрационного приложения указывается идентификатор приложения. Он также настраивает среду выполнения и SDK:

id: org.flathub.electron-sample-app
runtime: org.freedesktop.Platform
runtime-version: '23.08'
sdk: org.freedesktop.Sdk

Среда выполнения Freedesktop, как правило, является лучшей средой выполнения для использования с приложениями Electron, поскольку это минимальная среда выполнения, а другие зависимости будут специфичными для самого Electron.

Базовое приложение Electron

Затем в манифесте указывается, что следует использовать базовое приложение Electron, путем указания свойств base и base-version в манифесте приложения:

base: org.electronjs.Electron2.BaseApp
base-version: '23.08'

Базовые приложения описаны в Зависимости. Использование базового приложения Electron намного быстрее и удобнее, чем создание зависимостей Electron вручную. Это также имеет то преимущество, что уменьшает количество дублирований на машинах пользователей, поскольку это означает, что Electron сохраняется на диске только один раз.

Расширение SDK для Node.js

Чтобы создавать приложения на основе Electron, вам понадобится Node.js, доступный во время сборки. Flathub предоставляет версии LTS для Node.js в качестве расширений для SDK, поэтому вы можете установить одну из них и добавить ее в манифест приложений:

sdk-extensions:
  - org.freedesktop.Sdk.Extension.node18

Включите расширение, добавив его в «PATH»:

build-options:
  append-path: /usr/lib/sdk/node18/bin

Обратите внимание, что имя расширения (последняя часть нотации обратного DNS, «node18» в этом примере) должно быть одинаковым в «sdk-extensions» и «append-path».

Command

Свойство command указывает, что для запуска приложения должен быть выполнен сценарий с именем run.sh. Это будет объяснено более подробно позже.

command: run.sh

Разрешения песочницы

The standard guidelines on sandbox permissions apply to Electron applications. However, Electron does not use Wayland by default. So for display access, only X11 should be used as the default configuration. This will make Electron use Xwayland in a wayland session and nothing else is required.

The sample app also configures pulseaudio for sound and enables network access.

finish-args:
  - --share=ipc
  - --socket=x11
  - --socket=pulseaudio
  - --share=network
  - --env=ELECTRON_TRASH=gio

Примечание

Native wayland support in electron is experimental and often unstable. It is advised to stick with the X11 and Xwayland configuration above as the default.

To enable experimental native Wayland support in Electron>=20, the --ozone-platform-hint=auto flag can be passed to the program. auto will choose Wayland when the session is wayland and Xwayland or X11 otherwise.

The recommended option is to leave it to the user. So --socket=x11 should be used in manifest and Wayland can be tested with:

flatpak run --socket=wayland org.flathub.electron-sample-app

To make native wayland the default for users --socket=fallback-x11 and --socket=wayland must be used in the manifest.

Client-side window decorations in native wayland can be enabled by passing --enable-features=WaylandWindowDecorations (Electron>=17).

Electron uses libnotify on Linux to provide desktop notifications. libnotify since 0.8.0 automatically uses the notification portal when inside a sandboxed environment and --talk-name=org.freedesktop.Notifications is not required.

org.electronjs.Electron2.BaseApp since branch/23.08 comes with libnotify>=0.8.0

Using correct desktop file name

It’s important for Linux applications to set the correct desktop file name. If not, it can lead to problems like missing the window icon under Wayland. By default Electron uses {appname}.desktop as desktop file name. In Flatpak the name of the desktop file must be the id of the Flatpak. To tell Electron to use another name you need to set the desktopName key in your package.json e.g. "desktopName": "com.example.MyApp.desktop".

In case you repack a binary, you can use the patch-desktop-filename script provided by the BaseApp. Each Electron binary ships with resources/app.asar file. You need to call patch-desktop-filename with this file as argument. If your application is installed under ${FLATPAK_DEST}/my-app you need to run patch-desktop-filename ${FLATPAK_DEST}/my-app/resources/app.asar.

Варианты сборки

Эти параметры сборки не являются обязательными, но могут быть полезны, если что-то пойдет не так. env позволяет установить массив переменных среды, в этом случае мы устанавливаем NPM_CONFIG_LOGLEVEL на info, чтобы npm давал нам более подробные сообщения об ошибках.

build-options:
  cflags: -O2 -g
  cxxflags: -O2 -g
  env:
    NPM_CONFIG_LOGLEVEL: info

Модуль приложения

Последний раздел манифеста определяет, как должен быть построен модуль приложения. Здесь можно найти дополнительную логику для Electron и Node.js.

По умолчанию flatpak-builder не разрешает инструментам сборки доступ к сети. Это означает, что инструменты, которые полагаются на источники загрузки, не будут работать. Поэтому пакеты Node.js необходимо загрузить до запуска сборки. Установка переменной окружения electronic_config_cache означает, что они будут найдены при сборке.

Следующая часть манифеста описывает, как должно быть создано приложение. Используется опция simple buildsystem, которая позволяет указать последовательность команд, используемых для сборки. Также указывается место загрузки и хеш приложения.

name: electron-sample-app
buildsystem: simple
build-options:
  env:
    XDG_CACHE_HOME: /run/build/electron-sample-app/flatpak-node/cache
    npm_config_cache: /run/build/electron-sample-app/flatpak-node/npm-cache
    npm_config_nodedir: /usr/lib/sdk/node18
    npm_config_offline: 'true'
subdir: main
sources:
  - type: archive
    url: https://github.com/flathub/electron-sample-app/archive/1.0.1.tar.gz
    sha256: a2feb3f1cf002a2e4e8900f718cc5c54db4ad174e48bfcfbddcd588c7b716d5b
    dest: main

Объединение пакетов NPM

В следующей строке показано, как модули NPM объединяются как часть Flatpaks:

- generated-sources.json

Поскольку даже простые приложения Node.js зависят от десятков пакетов, было бы нецелесообразно указывать их все как часть файла манифеста. Поэтому был разработан скрипт Python для загрузки пакетов Node.js с помощью NPM или Yarn и включения их в исходный код приложения.

Для скрипта Python требуется файл package-lock.json (или yarn.lock). Этот файл содержит информацию о пакетах, от которых зависит приложение, и может быть сгенерирован запуском npm install --package-lock-only из корневого каталога приложения. Затем скрипт запускается следующим образом:

$ flatpak-node-generator npm package-lock.json

Это генерирует манифест JSON, необходимый для сборки пакетов NPM/Yarn для приложения, которые выводятся в файл с именем generated-sources.json. Содержимое этого файла можно скопировать в манифест приложения, но, поскольку он часто очень длинный, часто лучше сделать ссылку на него из основного манифеста, что делается путем добавления generated-source.json в качестве строка в разделе манифеста, как показано выше.

Запуск приложения

Приложение Electron запускается с помощью простого скрипта. Этому может быть присвоено любое имя, но оно должно быть указано в свойстве "command": манифеста. Ниже приведен пример оболочки для запуска приложения:

- type: script
  dest-filename: run.sh
  commands:
    - zypak-wrapper.sh /app/main/electron-sample-app "$@"

Команды сборки

И последнее, но не менее важное: поскольку используется простая опция сборки, необходимо предоставить список команд сборки. Как видно, npm запускается с переменной среды npm_config_offline=true, устанавливая зависимости от пакетов, которые уже были кэшированы. Они копируются в /app/main/. Наконец, скрипт run.sh устанавливается в /app/bin/, так что он будет находиться в $PATH:

build-commands:
  # Install npm dependencies
  - npm install --offline
  # Build the app; in this example the `dist` script
  # in package.json runs electron-builder
  - |
    . ../flatpak-node/electron-builder-arch-args.sh
    npm run dist -- $ELECTRON_BUILDER_ARCH_ARGS  --linux --dir
  # Bundle app and dependencies
  - cp -a dist/linux*unpacked /app/main
  # Install app wrapper
  - install -Dm755 -t /app/bin/ ../run.sh

Обратите внимание: если приложение, которое вы пытаетесь упаковать, содержит блок build в package.json с инструкциями для Linux, это может привести к тому, что electron-builder попытается получить дополнительные двоичные файлыво время сборки. (Даже если используется опция –dir). В следующем примере показана конфигурация, которая попытается загрузить двоичные файлы AppImage:

"build": {
  "linux": {
    "target": "AppImage",
  }
}

Предпочтительный способ исправить это - не патч, а редактирование во время сборки с использованием jq. Следующая команда заменит "target": "AppImage" на "target": "dir":

jq '.build.linux.target="dir"' <<<$(<package.json) > package.json

Make setProgressBar and setBadgeCount work

The setProgressBar and setBadgeCount functions allow showing a progress bar and a badge count in the window icon. It is implemented under Linux using the UnityLauncherAPI. This API is not implemented on every desktop environment. A known desktop environment which implements this is KDE. It is also implemented by the popular Dash to Dock GNOME extension and Plank.

To make it work in Flatpak, the app needs to use the correct desktop filename. The Flatpak also needs the --talk-name=com.canonical.Unity permission.

Electron checks checks if it’s running on Unity or KDE before using the UnityLauncherAPI. To make this work on other Desktops too, you need to set XDG_CURRENT_SESSION=KDE and XDG_CURRENT_DESKTOP=KDE to pretend the app is running on KDE.