Electron 應(yīng)用打包

2020-08-06 09:56 更新

Electron 應(yīng)用打包

為舒緩 Windows 下路徑名過長的問題  ,也略對 require 加速以及簡單隱匿你的源代碼,你可以通過極小的源代碼改動將你的應(yīng)用打包成  asar 文件。

生成 asar 包

asar 是一種將多個文件合并成一個文件的類 tar 風(fēng)格的歸檔格式。Electron 可以無需解壓整個文件,就能夠從其中讀取任意文件內(nèi)容。

參照如下步驟將你的應(yīng)用打包成 asar文件:

1. 安裝 asar

$ npm install -g asar

2. 用 asar pack 打包

$ asar pack your-app app.asar

使用 asar 檔案文件

在 Electron 中有兩類 APIs:Node.js 提供的 Node API 和 Chromium 提供的 Web API。這兩種 API 都支持從 asar 包中讀取文件。

Node API

由于 Electron 中打了特別補丁, Node API 中如 fs.readFile 或者 require 之類的方法可以將 asar 視之為虛擬文件夾,讀取 asar 里面的文件就和從真實的文件系統(tǒng)中讀取一樣。

例如,假設(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');

列出 asar 包中根目錄下的所有文件:

const fs = require('fs');
fs.readdirSync('/path/to/example.asar');

使用 asar 包中的一個模塊:

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

你也可以使用 BrowserWindow 來顯示一個 asar 包里的 web 頁面:

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: 協(xié)議可以獲取 asar 包中文件。和 Node API 一樣,視 asar 包如虛擬文件夾。

例如,用 $.get 獲取文件:

<script>
var $ = require('./jquery.min.js');
$.get('file:///path/to/example.asar/file.txt', function(data) {
  console.log(data);
});
</script>

把 asar 檔案當(dāng)作一個普通的文件

某些情況下,如:對 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')

Node API 缺陷

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

asar 包是只讀的

asar 包中的內(nèi)容不可更改,所以 Node APIs 里那些可以用來修改文件的方法在對待 asar 包時都無法正常工作。

Working Directory 在 asar 包中無效

盡管 asar 包是虛擬文件夾,但其實并沒有真實的目錄架構(gòu)對應(yīng)在文件系統(tǒng)里,所以你不可能將 working Directory 設(shè)置成 asar 包里的一個文件夾。將 asar 中的文件夾以 cwd 形式作為參數(shù)傳入一些 API 中也會報錯。

API 中需要額外解壓的檔案包

大部分 fs API 可以無需解壓即從 asar 包中讀取文件或者文件的信息,但是在處理一些依賴真實文件路徑的底層系統(tǒng)方法時,Electron 會將所需文件解壓到臨時目錄下,然后將臨時目錄下的真實文件路徑傳給底層系統(tǒng)方法使其正常工作。 對于這類API,花銷會略多一些。

以下是一些需要額外解壓的 API:

  • child_process.execFile
  • child_process.execFileSync
  • fs.open
  • fs.openSync
  • process.dlopen - 用在 require 原生模塊時 

fs.stat 獲取的 stat 信息不可靠

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

執(zhí)行 asar 包中的程序

Node 中有一些可以執(zhí)行程序的 API,如 child_process.exec,child_process.spawn 和 child_process.execFile 等,但只有 execFile 可以執(zhí)行 asar 包中的程序。

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

打包時排除文件

如上所述,一些 Node API 會在調(diào)用時將文件解壓到文件系統(tǒng)中,除了效率問題外,也有可能引起殺毒軟件的注意!

為解決這個問題,你可以在生成 asar 包時使用 --unpack 選項來排除一些文件,使其不打包到 asar 包中,下面是如何排除一些用作共享用途的 native 模塊的方法:

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

經(jīng)過上述命令后,除了生成的

app.asar

包以外,還有一個包含了排除文件的

app.asar.unpacked

文件夾,你需要將這個文件夾一起拷貝,提供給用戶。


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號