爲舒緩 Windows
下路徑名過長的問題 issues
,稍微加快 require
的速度以及簡單隱匿源代碼,咱們能夠選擇把應用打包成 asar
檔案文件,這隻須要對源代碼作一些很小的改動。大部分用戶能夠輕鬆實現這個功能,由於它在 electron-packager
、electron-forge
和 electron-builder
中都獲得了支持,開箱即用。css
生成asar包
asar
是一種將多個文件合併成一個文件的類 tar
風格的歸檔格式。Electron
無需解壓整個文件,就能夠從其中讀取任意文件內容。 能夠按以下步驟來將應用打包成 asar
:html
- 安裝
asar
:
$ npm install -g asar
- 使用
asar pack
打包:
$ asar pack your-app app.asar
使用asar包
在 Electron
中有兩類 APIs
,分別是 Node.js
提供的 Node API
和 Chromium
提供的 Web API
。這兩種 API
都支持從 asar
包中讀取文件。node
Node API
因爲 Electron
中打了特別補丁, Node API
中如 fs.readFile
或者 require
之類的方法能夠將 asar
視之爲虛擬文件夾,讀取 asar
裏面的文件就和從真實的文件系統中讀取同樣。jquery
示例:
例如假設咱們在 /path/to
文件夾下有個 example.asar
包:shell
$ asar list /path/to/example.asar /app.js /file.txt /dir/module.js /static/index.html /static/main.css /static/jquery.min.js
從 asar
包讀取一個文件:npm
const fs = require('fs'); fs.readFileSync('/path/to/example.asar/file.txt');
列出 asar
包中根目錄下的全部文件:架構
const fs = require('fs'); fs.readdirSync('/path/to/example.asar');
使用 asar
包中的一個模塊:app
const BrowserWindow = require('electron').BrowserWindow; var win = new BrowserWindow({width: 800, height: 600}); win.loadURL('file:///path/to/example.asar/static/index.html');
Web API
在 Web
頁面裏,用 file:
協議能夠獲取 asar
包中文件。和 Node API
同樣,視 asar
包如虛擬文件夾。electron
示例:
例如能夠使用 $.get
來獲取文件:ui
<script> var $ = require('./jquery.min.js'); $.get('file:///path/to/example.asar/file.txt', function(data) { console.log(data); }); </script>
把asar包看成一個普通的文件
某些狀況下,例如對 asar
包文件進行校驗,咱們須要像讀取 「文件」 那樣讀取 asar
包文件。 爲此咱們能夠使用內置的沒有 asar
功能的和原始 fs
模塊如出一轍的 original-fs
模塊。
示例:
const originalFs = require('original-fs') originalFs.readFileSync('/path/to/example.asar')
也能夠將 process.noAsar
設置爲 true
,用來禁用 fs
模塊中對 asar
的支持:
const fs = require('fs') process.noAsar = true fs.readFileSync('/path/to/example.asar')
Node API缺陷
儘管咱們已經盡了最大努力使得 asar
包在 Node API
下的應用盡量的趨向於真實的目錄結構,但仍有一些底層 Node API
咱們沒法保證其正常工做。
asar包文件是隻讀的
asar
包中的內容不可更改,因此 Node APIs
裏那些能夠用來修改文件的方法在對待 asar
包時都沒法正常工做。
工做目錄在 asar 包中無效
儘管 asar
包是虛擬文件夾,但其實並無真實的目錄架構對應在文件系統裏,因此咱們不可能將工做目錄 working Directory
設置成 asar
包裏的一個文件夾。將 asar
中的文件夾以 cwd
形式做爲參數傳入一些 API
中也會報錯。
某些API須要額外解壓的asar包
大部分 fs
能夠無需解壓即從 asar
包中讀取文件或者文件的信息,可是在處理一些依賴真實文件路徑的底層系統方法時,Electron
會將所需文件解壓到臨時目錄下,而後將臨時目錄下的真實文件路徑傳給底層系統方法使其正常工做。 對於這類 API
,花銷會略多一些。
如下是一些須要額外解壓的 API
:
child_process.execFile
child_process.execFileSync
fs.open
fs.openSync
process.dlopen
fs.stat的不真實統計信息
對 asar
包中的文件取 fs.stat
,返回的 Stats
對象不是精確值,由於這些文件不是真實存在於文件系統裏。因此除了文件大小和文件類型之外,咱們不該該依賴 Stats
對象的值。
執行asar包中的二進制文件
Node
中有一些能夠執行程序的 API
,如 child_process.exec
,child_process.spawn
和 child_process.execFile
等,但只有 execFile
能夠執行 asar
包中的程序。
由於 exec
和 spawn
容許 command
替代 file
做爲輸入,而 command
是須要在 shell
下執行的,目前沒有可靠的方法來判斷 command
中是否在操做一個 asar
包中的文件,並且即使能夠判斷,咱們依舊沒法保證能夠在無任何反作用的狀況下替換 command
中的文件路徑。
添加未打包的文件到asar包
一些 Node API
會在調用時將文件解壓到文件系統中,除了效率問題外,也有可能引發殺毒軟件的注意!
爲解決這個問題,咱們能夠在生成 asar
包時使用 --unpack
選項來排除一些文件,使其不打包到 asar
包中,下面是如何排除一些用做共享用途的 native
模塊的方法:
$ asar pack app app.asar --unpack *.node
通過上述命令後,除了生成的 app.asar
包之外,還有一個包含了排除文件的 app.asar.unpacked
文件夾,咱們須要將這個文件夾一塊兒拷貝,提供給用戶。