ASAR アーカイブ
アプリケーションの配布を作成した後、アプリのソースコードは通常、ASAR アーカイブにバンドルされます。これは、Electron アプリ用に設計されたシンプルな拡張アーカイブ形式です。アプリをバンドルすることで、Windows の長いパス名に関する問題を軽減し、require
を高速化し、簡単な検査からのソースコードを隠すことができます。
バンドルされたアプリは仮想ファイルシステムで実行され、ほとんどの API は通常どおり動作しますが、いくつかの注意点のため、ASAR アーカイブを明示的に操作したい場合があります。
ASAR アーカイブの使用
Electron には、Node.js が提供する Node API と、Chromium が提供する Web API の 2 つの API セットがあります。どちらの API も ASAR アーカイブからのファイルの読み取りをサポートしています。
Node API
Electron の特別なパッチにより、fs.readFile
や require
などの Node API は ASAR アーカイブを仮想ディレクトリとして、その中のファイルをファイルシステムの通常のファイルとして扱います。
たとえば、/path/to
の下に example.asar
アーカイブがあるとします。
$ asar list /path/to/example.asar
/app.js
/file.txt
/dir/module.js
/static/index.html
/static/main.css
/static/jquery.min.js
ASAR アーカイブ内のファイルの読み取り
const fs = require('node:fs')
fs.readFileSync('/path/to/example.asar/file.txt')
アーカイブのルートの下にあるすべてのファイルのリスト表示
const fs = require('node:fs')
fs.readdirSync('/path/to/example.asar')
アーカイブからのモジュールの使用
require('./path/to/example.asar/dir/module.js')
BrowserWindow
を使用して、ASAR アーカイブ内のウェブページを表示することもできます。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.loadURL('file:///path/to/example.asar/static/index.html')
Web API
ウェブページでは、アーカイブ内のファイルは file:
プロトコルで要求できます。Node API と同様に、ASAR アーカイブはディレクトリとして扱われます。
たとえば、$.get
でファイルを取得するには
<script>
let $ = require('./jquery.min.js')
$.get('file:///path/to/example.asar/file.txt', (data) => {
console.log(data)
})
</script>
ASAR アーカイブを通常のファイルとして扱う
ASAR アーカイブのチェックサムを確認するなど、いくつかのケースでは、ASAR アーカイブの内容をファイルとして読み取る必要があります。この目的のために、asar
サポートなしの元の fs
API を提供する組み込みの original-fs
モジュールを使用できます。
const originalFs = require('original-fs')
originalFs.readFileSync('/path/to/example.asar')
process.noAsar
を true
に設定して、fs
モジュールでの asar
のサポートを無効にすることもできます。
const fs = require('node:fs')
process.noAsar = true
fs.readFileSync('/path/to/example.asar')
Node API の制限事項
Node API で ASAR アーカイブをできる限りディレクトリのように動作させるために努力しましたが、Node API の低レベルの性質のために、依然として制限事項があります。
アーカイブは読み取り専用です
アーカイブは変更できないため、ファイルを修正できるすべての Node API は ASAR アーカイブでは機能しません。
作業ディレクトリをアーカイブ内のディレクトリに設定できません
ASAR アーカイブはディレクトリとして扱われますが、ファイルシステムには実際のディレクトリが存在しないため、作業ディレクトリを ASAR アーカイブ内のディレクトリに設定することはできません。一部の API の cwd
オプションとして渡すと、エラーが発生します。
一部の API での追加展開
ほとんどの fs
API は、展開せずに ASAR アーカイブからファイルを読み取るか、ファイルの情報を取得できますが、基になるシステムコールに実際のファイルパスを渡す必要がある一部の API の場合、Electron は必要なファイルを一時ファイルに抽出し、API が動作するように一時ファイルのパスを API に渡します。これにより、これらの API のオーバーヘッドが少し増加します。
追加の展開を必要とする API は次のとおりです。
child_process.execFile
child_process.execFileSync
fs.open
fs.openSync
process.dlopen
- ネイティブモジュールでのrequire
によって使用されます。
fs.stat
の偽の統計情報
asar
アーカイブ内のファイルに対する fs.stat
とその関連関数によって返される Stats
オブジェクトは、これらのファイルはファイルシステムに存在しないため、推測によって生成されます。そのため、ファイルサイズを取得したり、ファイルの種類を確認したりする場合を除き、Stats
オブジェクトを信頼しないでください。
ASAR アーカイブ内のバイナリの実行
child_process.exec
、child_process.spawn
、child_process.execFile
など、バイナリを実行できる Node API がありますが、execFile
のみが ASAR アーカイブ内のバイナリの起動をサポートしています。
これは、exec
と spawn
が file
ではなく command
を入力として受け入れるため、command
はシェルで実行されるためです。コマンドが asar アーカイブ内のファイルを使用しているかどうかを確実に判断する方法はなく、たとえそうであっても、副作用なしでコマンド内のパスを置き換えることができるかどうかを確実に確認することはできません。
展開済みファイルを ASAR アーカイブに追加する
上記のように、一部の Node API は呼び出されるとファイルをファイルシステムに展開します。パフォーマンスの問題に加えて、さまざまなウイルス対策スキャナーがこの動作によってトリガーされる可能性があります。
回避策として、--unpack
オプションを使用して、さまざまなファイルを展開せずに残しておくことができます。次の例では、ネイティブ Node.js モジュールの共有ライブラリはパックされません。
$ asar pack app app.asar --unpack *.node
コマンドを実行すると、app.asar
ファイルとともに app.asar.unpacked
という名前のフォルダーが作成されます。これには展開されたファイルが含まれており、app.asar
アーカイブと一緒に配布する必要があります。