在完成 應(yīng)用程序打包 后,應(yīng)用程序的源代碼通常會被綁定到 ASAR存檔 中,這是一種為 Electron 應(yīng)用程序而設(shè)計的簡易存檔格式。通過捆綁到應(yīng)用程序中,我們可以緩解 Windows 上加載長路徑名稱的問題,加速加載并隱藏你的源碼, 避免粗略的檢查。 通過捆綁到應(yīng)用程序中,我們可以緩解 Windows 上加載長路徑名稱的問題,加速加載并隱藏你的源碼, 避免粗略的檢查。
打包后的應(yīng)用運行在一個虛擬文件系統(tǒng)并且大多數(shù)API都可以正常執(zhí)行, 但有些時候你可能在某種情況下需要在 ASAR 壓縮文件內(nèi)執(zhí)行.
Electron 有兩套 API:Node API 和 Web API 分別由 Node.js 和 Chromium 提供。 兩套 API 都支持都支持從 ASAR 包內(nèi)讀取文件.
由于 Electron 的特殊補丁程序, Node API 比如 fs.readFile
和 require
使用 ASAR 就像是使用虛擬目錄一樣, 里面的文件也像是在文件系統(tǒng)內(nèi)一樣.
例如,假設(shè)我們在 /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('fs')
fs.readFileSync('/path/to/example.asar/file.txt')
列出檔案根目錄下的所有文件:
const fs = require('fs')
fs.readdirSync('/path/to/example.asar')
使用檔案中的模塊:
require('./path/to/example.asar/dir/module.js')
你也可以在 ASAR 存檔內(nèi)使用 BrowserWindow
來顯示一個網(wǎng)絡(luò)頁面:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.loadURL('file:///path/to/example.asar/static/index.html')
在網(wǎng)頁中,可以使用 file:
協(xié)議請求歸檔中的文件。 就像是 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 文件。 為此你可以使用內(nèi)置的沒有asar
功能的和原始fs
模塊一模一樣的original-fs
模塊。
const originalFs = require('original-fs')
originalFs.readFileSync('/path/to/example.asar')
您也可以將 process.noAsar
設(shè)置為 true
以禁用 fs
模塊中對 asar
的支持:
const fs = require('fs')
process.noAsar = true
fs.readFileSync('/path/to/example.asar')
盡管我們已經(jīng)盡了最大努力使得 ASAR 文件使用 Node API 時的應(yīng)用盡可能的趨向于真實的目錄結(jié)構(gòu),但仍有一些底層 Node API 我們無法保證其正常工作。
歸檔文件中的內(nèi)容不可更改,所以 Node APIs 里那些會修改文件的方法在使用 ASAR 文件時都無法正常工作.
盡管 ASAR 檔案被視為目錄,但文件系統(tǒng)中沒有實際目錄,因此您永遠不能將工作目錄設(shè)置為 ASAR 檔案中的目錄。將 asar 中的文件夾以 cwd
形式作為參數(shù)傳入一些 API 中也會報錯。
大多數(shù) fs API 可以在不解包的情況下從 ASAR 檔案中讀取文件或獲取文件的信息,但是對于一些依賴于將真實文件路徑傳遞給底層系統(tǒng)調(diào)用的 API,Electron 會將需要的文件提取到一個臨時文件中,并將路徑傳遞給API 的臨時文件,使它們工作。對于這類API,會增加一些開銷。
以下是一些需要額外解壓的 API:
child_process.execFile
child_process.execFileSync
fs.open
fs.openSync
process.dlopen
- 用在 require
原生模塊時對 asar
檔案中的文件取 fs.stat
,返回的 Stats
對象不是精確值,因為這些文件不是真實存在于文件系統(tǒng)里。 所以除了文件大小和文件類型以外,你不應(yīng)該依賴 Stats
對象的值。
有可以執(zhí)行二進制文件的節(jié)點 API,如 child_process.exec、child_process.spawn 和 child_process.execFile,但僅支持 execFile 執(zhí)行 ASAR 存檔內(nèi)的二進制文件。
因為 exec
和 spawn
允許 command
替代 file
作為輸入,而 command
是需要在 shell 下執(zhí)行的. 目前沒有 可靠的方法來判斷 command 中是否在操作一個 asar 包中的文件,而且即便可以判斷,我們依舊無法保證可以在無任何 副作用的情況下替換 command 中的文件路徑。
如上所述,某些 Node API 被調(diào)用時會解壓文件到文件系統(tǒng)。 除了性能問題外,可能會觸犯各種防病毒掃描程序。
作為解決方法,您可以使用 --unpack 選項將各種文件解壓。在以下示例中,不會打包原生 Node.js 模塊的共享庫:
$ asar pack app app.asar --unpack *.node
運行命令后,您將會看到 app.asar.unpacked
文件夾與 app.asar
文件一起被創(chuàng)建了。 沒有被打包的文件和 app.asar
會一起存檔發(fā)布。
更多建議: