Aller au contenu principal

Archives ASAR

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.

L’application fournie s’exécute dans un système de fichiers virtuel et la plupart des API peuvent fonctionner normalement, cependant, dans certains cas, vous devrez-être travailler explicitement sur les archives ASAR en raison de certains problèmes.

Utilisation des archives ASAR

Electron possède deux jeux d'APIs différents : les APIs Node fournis par Node.js et les APIs Web fournis par Chromium. Ces deux API prennent en charge la lecture des fichiers d'archive ASAR.

Node API

Avec des correctifs spéciaux dans Electron, les API Node comme fs.readFile et require traiteront les archives ASAR comme des répertoires virtuels, et les fichiers qu’il contienent comme des fichiers normaux du système de fichiers.

Par exemple, supposons que nous ayons une archive exemple.asar dans /chemin/vers :

$ asar list /chemin/vers/exemple.asar
/app.js
/file.txt
/dir/module.js
/static/index.html
/static/main.css
/static/jquery.min.js

Lecture d'un fichier de l’archive ASAR :

const fs = require('node:fs')
fs.readFileSync('/chemin/vers/exemple.asar/fichier.txt')

Lister tous les fichiers à la racine de l’archive :

const fs = require('node:fs')
fs.readdirSync('/chemin/vers/exemple.asar')

Utiliser un module de l’archive :

require('./path/to/example.asar/dir/module.js')

Vous pouvez également afficher une page web provenant de l'archive ASAR avec BrowserWindow :

const { BrowserWindow } = require('electron')
const win = new BrowserWindow()

win.loadURL('file:///path/to/example.asar/static/index.html')

Web API

Dans une page web, on peut également aller chercher des fichiers d'une archive en utilisant le protocole file:. Les archives ASAR sont, de la même façon que l'API Node, traitées comme des répertoires.

Par exemple, pour obtenir un fichier avec $.get:

<script>
let $ = require('./jquery.min.js')
$.get('file:///chemin/vers/exemple.asar/fichier.txt', (data) => {
console.log(data)
})
</script>

Traitement d'une archive comme un fichier normal

Dans certains cas comme la vérification de la checksum d'une archive , il est nécessaire de lire le contenu d'une archive sous forme de fichier. Pour cela, vous pouvez utiliser le module original-fs intégré qui fournit l'API fs sans le support de asar :

const originalFs = require('original-fs')
originalFs.readFileSync('/chemin/vers/exemple.asar')

Vous pouvez également définir process.noAsar à true pour désactiver le support de asar dans le module fs :

const fs = require('node:fs')
process.noAsar = true
fs.readFileSync('/chemin/vers/exemple.asar')

Limites de l'API Node

Même si nous nous sommes efforcés de rendre le fonctionnement des archives ASAR de l'API Node identique à celui des répertoires , il demeure encore certaines limitations en raison de la nature bas niveau de l'API Node.

Les archives sont en lecture seule

Les archives ne sont pas modifiables, donc toutes les APIs Node étant en mesure de modifier les fichiers ne fonctionneront pas avec les archives .

Le dossier de travail ne peut pas être défini comme dossier dans une archive

Bien que les archives ASAR soient traitées comme des répertoires, ceux-ci ne sont pas de répertoires réels du système de fichiers, ainsi, vous ne pouvez pas attribuer le répertoire de travail à des répertoires dans les archives ASAR. Les passer en tant qu'option de cwd de certaines APIs occasionnera aussi des erreurs.

Dépaquetage supplémentaire sur certaines APIs

La plupart des API fs peuvent lire un fichier ou obtenir les informations d’un fichier à partir d'archives ASAR sans avoir à les décompresser, mais pour certaines API reposant sur la transmission du chemin absolu aux appels système sous-jacents, Electron extraira le fichier nécessaire dans un fichier temporaire et transmettra le chemin du fichier temporaire aux API pour les faire fonctionner. Cela ajoute un traitement supplémentaire pour ces APIs.

Les APIs qui requièrent un dépaquetage supplémentaire sont :

  • child_process.execFile
  • child_process.execFileSync
  • fs.open
  • fs.openSync
  • process.dlopen - utilisé par require sur des modules natifs

Fausses informations Stat de fs.stat

Les objets Stats retournés par les méthodes telles que fs.stat à partir de fichiers dans les archives asar sont générés par déduction puisque ces fichiers n'existent pas dans le système de fichiers. Donc vous ne devriez pas faire confiance aux objets Stats sauf pour obtenir la taille du fichier et vérifier le type de fichier.

Exécution de binaires dans une archive ASAR

Certaines API de Node peuvent exécuter des fichiers binaires tels que child_process.exec, child_process.spawn et child_process.execFile, mais seul execFile est pris en charge pour exécuter les fichiers binaires d'une archive ASAR`.```.

C'est parce que exec et spawn acceptent command au lieu de file en entrée, et les command sont exécutées sous shell. Il n'y a pas de moyen fiable de déterminer si une commande utilise un fichier dans une archive asar, et même si nous le faisons, nous ne pouvons pas être sûrs de pouvoir remplacer les chemins d'accès dans la commande sans effets secondaires.

Ajout de fichiers non empaquetés aux archives ASAR

Comme indiqué plus haut, certaines API Node décompresseront le fichier dans le système de fichiers lors de leur appel. En dehors des problèmes de performance que cela peut apporter, plusieurs scanners anti-virus pourraient être déclenchés par ce comportement.

Comme solution de contournement, vous pouvez laisser divers fichiers décompressés en utilisant l'option --unpack. Dans l'exemple suivant, les bibliothèques partagées des modules natifs Node.js ne seront pas empaquetées :

$ asar pack app app.asar --unpack *.node

Après avoir exécuter la commande, vous remarquerez qu'un dossier nommé app.asar.unpacked a été créé avec le fichier app.asar. Il contient les fichiers non-empaquetés et devrait être distribué avec l'archive app.asar.