ASAR Archiv
After creating an application distribution, the app's source code are usually bundled into an ASAR archive, which is a simple extensive archive format designed for Electron apps. By bundling the app we can mitigate issues around long path names on Windows, speed up require
and conceal your source code from cursory inspection.
The bundled app runs in a virtual file system and most APIs would just work normally, but for some cases you might want to work on ASAR archives explicitly due to a few caveats.
Using ASAR Archives
In Electron there are two sets of APIs: Node APIs provided by Node.js and Web APIs provided by Chromium. Both APIs support reading files from ASAR archives.
Node API
With special patches in Electron, Node APIs like fs.readFile
and require
treat ASAR archives as virtual directories, and the files in it as normal files in the filesystem.
Beispiel: Angenommen es existiert ein example.asar
-Archiv unter /path/to
:
$ asar list /path/to/example.asar
/app.js
/file.txt
/dir/module.js
/static/index.html
/static/main.css
/static/jquery.min.js
Read a file in the ASAR archive:
const fs = require('node:fs')
fs.readFileSync('/path/to/example.asar/file.txt')
Alle Dateien unterhalb der Archivwurzel auflisten:
const fs = require('node:fs')
fs.readdirSync('/path/to/example.asar')
Ein Modul aus dem Archiv nutzen:
require('./path/to/example.asar/dir/module.js')
You can also display a web page in an ASAR archive with BrowserWindow
:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.loadURL('file:///path/to/example.asar/static/index.html')
Web API
In a web page, files in an archive can be requested with the file:
protocol. Like the Node API, ASAR archives are treated as directories.
Zum Beispiel, Holen einer Datei mit $.get
:
<script>
let $ = require('./jquery.min.js')
$.get('file:///path/to/example.asar/file.txt', (data) => {
console.log(data)
})
</script>
Treating an ASAR archive as a Normal File
For some cases like verifying the ASAR archive's checksum, we need to read the content of an ASAR archive as a file. Zu diesem Zweck können Sie das integrierte original-fs
-Modul nutzen. Dieses stellt originale fs
APIs ohne asar
-Unterstützung bereit:
const originalFs = require('original-fs')
originalFs.readFileSync('/path/to/example.asar')
Sie können zudem den process.noAsar
auf true
setzen, um die Unterstützung für asar
im fs
-Modul zu deaktivieren:
const fs = require('node:fs')
process.noAsar = true
fs.readFileSync('/path/to/example.asar')
Einschränkungen der Node API
Even though we tried hard to make ASAR archives in the Node API work like directories as much as possible, there are still limitations due to the low-level nature of the Node API.
Archive sind Read-only
The archives can not be modified so all Node APIs that can modify files will not work with ASAR archives.
Festlegen von Arbeitsverzeichnissen innerhalb von Archiven nicht möglich
Though ASAR archives are treated as directories, there are no actual directories in the filesystem, so you can never set the working directory to directories in ASAR archives. Das Übergeben als cwd
-Option einiger APIs wird ebenfalls Fehler hervorbringen.
Zusätzliches Entpacken einiger APIs
Most fs
APIs can read a file or get a file's information from ASAR archives without unpacking, but for some APIs that rely on passing the real file path to underlying system calls, Electron will extract the needed file into a temporary file and pass the path of the temporary file to the APIs to make them work. Dies erhöht den Aufwand für diese APIs leicht.
APIs, die zusätzliches Entpacken benötigen sind:
child_process.execFile
child_process.execFileSync
fs.open
fs.openSync
process.dlopen
- verwendet vonrequire
bei nativen Modulen
Falsche Statusmeldung von fs.stat
Das Stats
Object, welches von fs.stat
zurückgegeben wird, und seine Freunde in Dateien in asar
-Archiven, wird durch Raten generiert, da diese Dateien nicht im Dateisystem existieren. Deshalb sollten Sie dem Stats
Objekt nicht trauen außer um die Dateigröße und Dateiart zu bestimmen.
Executing Binaries Inside ASAR archive
There are Node APIs that can execute binaries like child_process.exec
, child_process.spawn
and child_process.execFile
, but only execFile
is supported to execute binaries inside ASAR archive.
Das rührt daher, dass exec
und spawn
command
an Stelle von file
als Eingabe akzeptieren, und command
s in der Shell ausgeführt werden. Es existiert kein verlässlicher Weg herauszufinden, ob ein Command eine Datei in einem asar-Archiv nutzt. Und selbst wenn, kann man nicht sicher sein, ob man den Pfad im Command ohne Nebeneffekte austauschen kann.
Adding Unpacked Files to ASAR archives
As stated above, some Node APIs will unpack the file to the filesystem when called. Apart from the performance issues, various anti-virus scanners might be triggered by this behavior.
As a workaround, you can leave various files unpacked using the --unpack
option. In the following example, shared libraries of native Node.js modules will not be packed:
$ asar pack app app.asar --unpack *.node
After running the command, you will notice that a folder named app.asar.unpacked
was created together with the app.asar
file. It contains the unpacked files and should be shipped together with the app.asar
archive.