Формат ASAR: упаковка приложений Electron без усилий

Раздел: Разработка -> Electron и упаковка

Основы формата ASAR для упаковки Electron приложений

ASAR (Atom Shell Archive) – это архивный формат, используемый в Electron для объединения файлов приложения в один файл. Он ускоряет загрузку, уменьшает количество операций ввода-вывода и частично защищает исходный код. Ниже рассмотрены основные способы работы с ASAR.

Как упаковать приложение в ASAR с помощью пакета asar

Наиболее прямой способ – использование официального пакета @electron/asar. Он предоставляет CLI и Node API.

Установка

npm install -g @electron/asar

Js asar (формат asar в electron (упаковка приложений))

Создание архива

asar pack ./my-app ./my-app.asar

Команда pack упаковывает содержимое папки my-app в файл my-app.asar. По умолчанию создаётся упорядоченный архив, доступный для чтения через специальный протокол asar://.

Проверка содержимого

asar list my-app.asar

Команда выводит иерархию файлов внутри архива.

Извлечение файлов

asar extract my-app.asar ./output

Распаковывает архив в указанную директорию.

Типичные ошибки и их решение

  • Ошибка доступа к файлу – возникает, если пути содержат недопустимые символы или превышена длина. Решение: переименовать файлы, использовать более короткие имена.
  • Проблемы с кодировкой – при упаковке файлов с не-UTF8 именами. Решение: использовать файлы только с UTF-8 именами.
  • Архив большого размера – упаковка может занять много времени. Решение: исключить ненужные файлы (node_modules, исходники) с помощью опции --exclude-hidden.

Использование @electron/asar подходит для ручной упаковки и интеграции в скрипты сборки. Это основное решение, на котором базируются все остальные.

Как настроить electron-builder для автоматической упаковки в ASAR

Популярный сборщик electron-builder включает встроенную поддержку ASAR. Достаточно указать опции в package.json или конфигурационном файле.

{
  "build": {
    "asar": true,
    "asarUnpack": [
      "node_modules/needed-native-module/**"
    ]
  }
}

Флаг asar: true включает упаковку всех файлов в asar. Свойство asarUnpack перечисляет файлы, которые должны остаться вне архива (например, нативные модули).

Типичные ошибки и их решение

  • Нативные модули не загружаются – если модули требуют доступ к файловой системе (Node.js addon), их надо исключить через asarUnpack. Если забыть, приложение упадёт с ошибкой MODULE_NOT_FOUND.
  • Конфликт с автообновлением – при обновлении через electron-updater asar заменяется целиком, что может привести к сбоям. Решение: исключить конфигурационные файлы из asar.

Этот вариант предпочтителен для продакшен-сборок, так как автоматизирует процесс и обрабатывает исключения.

Как программно создать ASAR из Node.js скрипта

API пакета asar позволяет создавать архив из кода, что полезно для кастомных процессов сборки.

const { createPackage } = require('@electron/asar');

async function pack() {
  await createPackage('./app', './app.asar');
  console.log('Архив создан');
}
pack();

Для более тонкого контроля используется createPackageFromFiles, где можно указать список нужных файлов:

const { createPackageFromFiles } = require('@electron/asar');
const path = require('path');

const src = '/path/to/app';
const files = ['index.js', 'renderer.js', 'assets/'];
createPackageFromFiles(src, 'app.asar', files.map(f => path.join(src, f)));

Типичные ошибки и их решение

  • Ошибка при работе с символическими ссылками – API не обрабатывает их по умолчанию. Решение: предварительно разрешать ссылки или исключать их.
  • Превышение лимита памяти – при очень больших проектах. Решение: упаковывать по частям или использовать потоки.

Подходит для сложных сценариев, где нужно динамически формировать состав архива.

Как работать с ASAR через командную строку

Утилита asar предоставляет полноценный CLI для быстрого выполнения операций без Node.js кода.

# Упаковка
asar pack ./dist ./release/app.asar

# Извлечение
asar extract ./release/app.asar ./temp

# Список содержимого
asar list ./release/app.asar

Типичные ошибки и их решение

  • Команда не найдена – пакет не установлен глобально. Решение: установить через npm i -g @electron/asar.
  • Неверный формат архива – если asar-файл повреждён или создан другой утилитой. Решение: создать архив заново через asar pack.

CLI удобен для разовых операций и быстрой проверки.

Как настроить ASAR при упаковке через electron-packager

electron-packager также поддерживает asar через флаги.

npx electron-packager . MyApp --asar --asar-unpack=node_modules/some-module

Флаг --asar включает архивацию, --asar-unpack позволяет исключить подстроки пути. Можно указать несколько масок через запятую.

Типичные ошибки и их решение

  • Пропущенные файлы – если маска не соответствует реальной структуре. Решение: детально проверить пути в консоли после сборки.

Подходит для простых проектов, где нет сложной конфигурации сборки.

Расширенные примеры работы с ASAR

Полный цикл: упаковка, просмотр, распаковка

Установим asar, создадим архив, проинспектируем его и восстановим файлы.

Пример
# Установка
npm install -g @electron/asar

# Создание тестового проекта
mkdir test-app
cd test-app
echo 'console.log("Hello")' > index.js
echo '{"main":"index.js"}' > package.json
mkdir assets
touch assets/icon.png
cd ..

# Упаковка
asar pack test-app test-app.asar

# Список
asar list test-app.asar
test-app/
test-app/index.js
test-app/package.json
test-app/assets/
test-app/assets/icon.png
Пример
# Распаковка
asar extract test-app.asar ./extracted
tree extracted
extracted/
├── index.js
├── package.json
└── assets/
    └── icon.png

Архив полностью восстанавливается. Размер asar-файла обычно меньше исходной папки за счёт выравнивания данных.

Интеграция asar в npm скрипты

Добавим команды упаковки в package.json для автоматизации.

Пример
{
  "scripts": {
    "build": "webpack && node build.js",
    "pack:asar": "asar pack ./dist ./release/app.asar",
    "postbuild": "npm run pack:asar"
  }
}

После выполнения npm run build автоматически запустится упаковка в asar. Такой подход используется для CI/CD.

Настройка electron-builder с asarUnpack для нативных модулей

Нативный модуль node-canvas требует доступа к файлам вне архива. Пример конфигурации:

Пример
{
  "build": {
    "appId": "com.example.app",
    "asar": true,
    "asarUnpack": [
      "node_modules/canvas/build/**",
      "node_modules/canvas/*.node"
    ],
    "files": [
      "!node_modules/**/*",
      "!node_modules/canvas/build/**/*"
    ]
  }
}

Файлы в asarUnpack остаются вне архива, но копируются в папку приложения. Это гарантирует, что нативные бинарники будут доступны в файловой системе.

Просмотр структуры asar с помощью asar list

Команда asar list принимает дополнительные флаги, например, --pretty для форматированного вывода в JSON.

Пример
asar list app.asar --pretty
{
  "files": [
    {"path": "index.js", "size": 25, "offset": 0},
    {"path": "package.json", "size": 18, "offset": 512},
    {"path": "assets/icon.png", "size": 1024, "offset": 1536}
  ]
}

Позволяет увидеть смещения и размеры каждого файла. Это помогает отлаживать проблемы с доступом.

Замена файла внутри asar архива

Так как asar неизменяем, для замены файла требуется распаковать архив, удалить старый файл, добавить новый и переупаковать. Пример скрипта:

Пример
const { extract, createPackage } = require('@electron/asar');
const fs = require('fs-extra');
const path = require('path');

async function replaceFile(asarPath, targetPath, newContent) {
  const tempDir = './temp_asar';
  await extract(asarPath, tempDir);
  const fullTarget = path.join(tempDir, targetPath);
  await fs.outputFile(fullTarget, newContent);
  await createPackage(tempDir, asarPath.replace('.asar', '_v2.asar'));
  await fs.remove(tempDir);
  console.log('Архив обновлён');
}

Этот метод полезен для патчей без полной пересборки приложения.

Чтение файла из asar через Node.js

Electron монтирует asar как виртуальную файловую систему. Обычное чтение работает прозрачно, но если нужно обращаться к архиву вне контекста Electron, используется протокол asar://.

Пример
const fs = require('fs');
const pathInAsar = 'asar://' + path.resolve('./app.asar') + '/index.js';
const stream = fs.createReadStream(pathInAsar);
stream.on('data', chunk => console.log(chunk.toString()));

Обратите внимание: протокол asar:// доступен только внутри окружения Electron. Для обычного Node.js необходимо использовать API asar: fs.readFileSync(require.resolve('./app.asar/index.js')) после вызова asar.registerAsarFs (если такой модуль подключён).

Формат ASAR в Electron (упаковка приложений) - comments

En
Js asar (javascript)