Electron 應用打包

爲舒緩 Windows 下路徑名過長的問題 issues,稍微加快 require 的速度以及簡單隱匿源代碼,咱們能夠選擇把應用打包成 asar 檔案文件,這隻須要對源代碼作一些很小的改動。大部分用戶能夠輕鬆實現這個功能,由於它在 electron-packagerelectron-forgeelectron-builder 中都獲得了支持,開箱即用。css

生成asar包

asar 是一種將多個文件合併成一個文件的類 tar 風格的歸檔格式。Electron 無需解壓整個文件,就能夠從其中讀取任意文件內容。 能夠按以下步驟來將應用打包成 asarhtml

  • 安裝 asar
$ npm install -g asar
  • 使用 asar pack 打包:
$ asar pack your-app app.asar

使用asar包

Electron 中有兩類 APIs,分別是 Node.js 提供的 Node APIChromium 提供的 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.execchild_process.spawnchild_process.execFile 等,但只有 execFile 能夠執行 asar 包中的程序。

由於 execspawn 容許 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 文件夾,咱們須要將這個文件夾一塊兒拷貝,提供給用戶。

相關文章
相關標籤/搜索