2016-05-01 18:18:49 +00:00
|
|
|
|
# Упаковка приложения
|
|
|
|
|
|
|
|
|
|
Чтобы смягчить [проблемы](https://github.com/joyent/node/issues/6960) с длинными
|
2016-06-10 06:39:28 +00:00
|
|
|
|
именами под Windows, немного ускорить `require` и скрыть ваши исходные коды, Вы
|
2016-05-01 18:18:49 +00:00
|
|
|
|
можете упаковать его в архив [asar][asar], немного поменяв исходный код.
|
|
|
|
|
|
|
|
|
|
## Генерация архива `asar`
|
|
|
|
|
|
|
|
|
|
Архив [asar][asar] - простой фомат похожий на tar, который собирает много файлов
|
|
|
|
|
в один. Electron может читать такой файл без распаковки.
|
|
|
|
|
|
|
|
|
|
Шаги для упавки вашего приложения архив `asar`:
|
|
|
|
|
|
|
|
|
|
### 1. Установите саму утилиту asar
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ npm install -g asar
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2. Упакуйте с помощью `asar pack`
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ asar pack your-app app.asar
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Использование архивов `asar`
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
В Electron есть два вида API: API Node, которые устанавливаются с помощью Node.JS и
|
2016-05-01 18:18:49 +00:00
|
|
|
|
веб API, которые предоставляюся Chromium. Оба предоставляют возможность считывать из
|
|
|
|
|
архивов `asar`.
|
|
|
|
|
|
|
|
|
|
### Node API
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Со специальными патчами в Electron, части Node API вроде `fs.readFile` и `require`
|
2016-05-01 18:18:49 +00:00
|
|
|
|
считают архивы `asar` виртуальными папками и файлы в них доступны как в обычных.
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Например, у нас есть архив `example.asar` в `/path/to`:
|
2016-05-01 18:18:49 +00:00
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ asar list /path/to/example.asar
|
|
|
|
|
/app.js
|
|
|
|
|
/file.txt
|
|
|
|
|
/dir/module.js
|
|
|
|
|
/static/index.html
|
|
|
|
|
/static/main.css
|
|
|
|
|
/static/jquery.min.js
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Прочитаеем файл в архиве `asar`:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
fs.readFileSync('/path/to/example.asar/file.txt');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Список всех файлов начиная от корня архива:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
fs.readdirSync('/path/to/example.asar');
|
|
|
|
|
```
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Используем модуль из архива:
|
2016-05-01 18:18:49 +00:00
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
require('/path/to/example.asar/dir/module.js');
|
|
|
|
|
```
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Вы также можете показывать веб-страницы из архива `asar` через `BrowserWindow`:
|
2016-05-01 18:18:49 +00:00
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
const BrowserWindow = require('electron').BrowserWindow;
|
|
|
|
|
var win = new BrowserWindow({width: 800, height: 600});
|
|
|
|
|
win.loadURL('file:///path/to/example.asar/static/index.html');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Веб API
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
На веб-страницах файлы запрашиваются с помощью протокола `file:`. Как и в Node API
|
2016-05-01 18:18:49 +00:00
|
|
|
|
архивы `asar` считаются за директории.
|
|
|
|
|
|
|
|
|
|
Пример получения файла с помощью `$.get`:
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<script>
|
|
|
|
|
var $ = require('./jquery.min.js');
|
|
|
|
|
$.get('file:///path/to/example.asar/file.txt', function(data) {
|
|
|
|
|
console.log(data);
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Использование архива `asar` в качестве обычного файла
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Для случаев, когда Вам, например, нужно проверить хэш-сумму архива `asar`,
|
2016-05-01 18:18:49 +00:00
|
|
|
|
нужно использовать архив как файл. Для этой цели существует встроенный модуль
|
|
|
|
|
`original-fs`, который предоставляет доступ к `fs` без поддежки `asar`:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
var originalFs = require('original-fs');
|
|
|
|
|
originalFs.readFileSync('/path/to/example.asar');
|
|
|
|
|
```
|
2016-06-10 06:39:28 +00:00
|
|
|
|
|
2016-05-01 18:18:49 +00:00
|
|
|
|
Вы также можете выставить `process.noAsar` в `true`, чтобы выключить поддержку `asar`
|
|
|
|
|
в модуле `fs`:
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
process.noAsar = true;
|
|
|
|
|
fs.readFileSync('/path/to/example.asar');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Ограничения Node API
|
|
|
|
|
|
|
|
|
|
Хотя мы и старались как могли, чтобы сделать `asar` максимально похожим на папки,
|
2016-06-10 06:39:28 +00:00
|
|
|
|
всё ещё существуют некоторые ограничения из-за низкоуровневой архитектуры Node API.
|
2016-05-01 18:18:49 +00:00
|
|
|
|
|
|
|
|
|
### Архивы только для чтения
|
|
|
|
|
|
|
|
|
|
Архивы не могут быть изменены, так что все функции API Node, которые меняют файлы,
|
|
|
|
|
не буду работать с архивами `asar`.
|
|
|
|
|
|
|
|
|
|
### Нельзя установить рабочую директорию в архиве
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Хотя архивы `asar` и считаются папками, они ими на самом деле не являются ими,
|
|
|
|
|
так что Вы не можете установить в них рабочую директорию. Передача
|
2016-05-01 18:18:49 +00:00
|
|
|
|
архивов `asar` в качестве аргумента `cwd` некоторым API также может вызывать ошибки.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Распаковка для некоторых API
|
|
|
|
|
|
|
|
|
|
Большинство API `fs` могут читать файлы или получить сведения о них прямо из
|
|
|
|
|
архива, без распаковки, однако для некоторых, которые передают путь к системным
|
|
|
|
|
вызовам, Electron распакует нужный файл в временную папку и передаст путь к этому
|
|
|
|
|
файлу.
|
|
|
|
|
|
|
|
|
|
API которым нужна распаковка:
|
|
|
|
|
|
|
|
|
|
* `child_process.execFile`
|
|
|
|
|
* `child_process.execFileSync`
|
|
|
|
|
* `fs.open`
|
|
|
|
|
* `fs.openSync`
|
|
|
|
|
* `process.dlopen` - используется `require` на нативных модулях
|
|
|
|
|
|
|
|
|
|
### Подельная информация для `fs.stat`
|
|
|
|
|
|
|
|
|
|
Объект `Stats`, возвращаемый `fs.stat`, и его друзья для остальных файлов
|
|
|
|
|
в архиве `asar` специально генерируются, потому что на самом деле этих файлов
|
|
|
|
|
не существует в файловой системе. Вам не стоит доверять информации
|
|
|
|
|
из объектов `Stats`, кроме, разве что, размера и типа файлов.
|
|
|
|
|
|
|
|
|
|
### Запуск исполняемых файлов из архивов `asar`
|
|
|
|
|
|
|
|
|
|
Существуют некоторые API Node, которые исполняют файлы, например `child_process.exec`,
|
|
|
|
|
`child_process.spawn` и `child_process.execFile`, но только `execFile` может
|
|
|
|
|
исполнять файлы из архивов `asar`.
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Так вышло потому, что `exec` и `spawn` принимают `команду`, а не `файл` как параметр,
|
2016-05-01 18:18:49 +00:00
|
|
|
|
а `команды` исполняются в оболочке. Нет никакой реальной возможности проверить,
|
|
|
|
|
реален ли файл или находится в архиве `asar`, и даже если мы смогли бы проверить,
|
|
|
|
|
то неясно, как земенить путь к файлу без побочных эффектов.
|
|
|
|
|
|
|
|
|
|
## Добавление распакованых файлов в архив `asar`
|
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Как говорилось выше, некоторые API Node будут распаковывать файлы,
|
2016-05-01 18:18:49 +00:00
|
|
|
|
чтобы их использовать. Кроме увеличенного потребления ресурсов это также
|
2016-06-10 06:39:28 +00:00
|
|
|
|
может вызвать предупреждения от антивирусов.
|
2016-05-01 18:18:49 +00:00
|
|
|
|
|
2016-06-10 06:39:28 +00:00
|
|
|
|
Чтобы обойти это, Вы можете распаковать некоторые файлы, создавая архивы,
|
2016-05-01 18:18:49 +00:00
|
|
|
|
с помощью опции `--unpack`. Пример показывает распаковку нативных модулей:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ asar pack app app.asar --unpack *.node
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
После запуска команды выше в вашей папке, кроме `app.asar`, появится
|
|
|
|
|
`app.asar.unpacked`, которая будет содержать распакованные файлы, эту
|
|
|
|
|
папку стоит копировать вместе с `app.asar` при распространении.
|
|
|
|
|
|
|
|
|
|
[asar]: https://github.com/atom/asar
|