Electron ASAR Archives

2023-02-16 17:16 更新

在完成 應(yīng)用程序打包 后,應(yīng)用程序的源代碼通常會被綁定到 ASAR存檔 中,這是一種為 Electron 應(yīng)用程序而設(shè)計的簡易存檔格式。通過捆綁到應(yīng)用程序中,我們可以緩解 Windows 上加載長路徑名稱的問題,加速加載并隱藏你的源碼, 避免粗略的檢查。 通過捆綁到應(yīng)用程序中,我們可以緩解 Windows 上加載長路徑名稱的問題,加速加載并隱藏你的源碼, 避免粗略的檢查。

打包后的應(yīng)用運(yùn)行在一個虛擬文件系統(tǒng)并且大多數(shù)API都可以正常執(zhí)行, 但有些時候你可能在某種情況下需要在 ASAR 壓縮文件內(nèi)執(zhí)行.

使用 ASAR 包?

Electron 有兩套 API:Node API 和 Web API 分別由 Node.js 和 Chromium 提供。 兩套 API 都支持都支持從 ASAR 包內(nèi)讀取文件.

Node API

由于 Electron 的特殊補(bǔ)丁程序, 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')

Web API

在網(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 歸檔文件進(jìn)行校驗,我們需要像讀取 “文件” 那樣讀取 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')

Node API 的局限性?

盡管我們已經(jīng)盡了最大努力使得 ASAR 文件使用 Node API 時的應(yīng)用盡可能的趨向于真實的目錄結(jié)構(gòu),但仍有一些底層 Node API 我們無法保證其正常工作。

檔案文件是只讀的?

歸檔文件中的內(nèi)容不可更改,所以 Node APIs 里那些會修改文件的方法在使用 ASAR 文件時都無法正常工作.

工作目錄不能設(shè)置為檔案文件里的目錄

盡管 ASAR 檔案被視為目錄,但文件系統(tǒng)中沒有實際目錄,因此您永遠(yuǎn)不能將工作目錄設(shè)置為 ASAR 檔案中的目錄。將 asar 中的文件夾以 cwd 形式作為參數(shù)傳入一些 API 中也會報錯。

某些 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 原生模塊時

fs.stat 的不真實統(tǒng)計信息

對 asar 檔案中的文件取 fs.stat,返回的 Stats 對象不是精確值,因為這些文件不是真實存在于文件系統(tǒng)里。 所以除了文件大小和文件類型以外,你不應(yīng)該依賴 Stats 對象的值。

執(zhí)行 ASAR 檔案中的二進(jìn)制文件

有可以執(zhí)行二進(jìn)制文件的節(jié)點(diǎn) API,如 child_process.exec、child_process.spawn 和 child_process.execFile,但僅支持 execFile 執(zhí)行 ASAR 存檔內(nèi)的二進(jìn)制文件。

因為 exec 和 spawn 允許 command 替代 file 作為輸入,而 command 是需要在 shell 下執(zhí)行的. 目前沒有 可靠的方法來判斷 command 中是否在操作一個 asar 包中的文件,而且即便可以判斷,我們依舊無法保證可以在無任何 副作用的情況下替換 command 中的文件路徑。

向 ASAR 檔案添加未打包的文件?

如上所述,某些 Node API 被調(diào)用時會解壓文件到文件系統(tǒng)。 除了性能問題外,可能會觸犯各種防病毒掃描程序。

作為解決方法,您可以使用 --unpack 選項將各種文件解壓。在以下示例中,不會打包原生 Node.js 模塊的共享庫:

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

運(yùn)行命令后,您將會看到 app.asar.unpacked 文件夾與 app.asar 文件一起被創(chuàng)建了。 沒有被打包的文件和 app.asar 會一起存檔發(fā)布。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號