electron/docs-translations/zh-TW/tutorial/application-packaging.md

168 lines
5.7 KiB
Markdown
Raw Normal View History

# 應用程式打包
為了減少圍繞著 Windows 上長路徑名稱問題的 [issues](https://github.com/joyent/node/issues/6960) ,稍微地加速 `require` 和隱藏你的原始碼避免不小心被看到,你可以選擇把你的應用程式打包成一個 [asar][asar] 壓縮檔,只需要改變一點點你的原始碼就好。
## 產生 `asar` 壓縮檔
一個 [asar][asar] 壓縮檔是一個簡單的類 tar 格式的檔案,它會把幾個檔案串接成一個檔案, Electron 可以不需要解壓縮整個檔案就從中讀取任意檔案。
把你的應用程式打包成 `asar` 壓縮檔的步驟:
### 1. 安裝 asar 工具包
```bash
$ npm install -g asar
```
### 2. 用 `asar pack` 打包
```bash
$ asar pack your-app app.asar
```
## 使用 `asar` 壓縮檔
在 Electron 中有兩組 APINode.js 提供的 Node APIs 和 Chromium 提供的 Web
APIs兩組 API 都支援從 `asar` 壓縮檔中讀取檔案。
### Node API
因為 Electron 中有一些特別的補釘,像是 `fs.readFile``require` 這樣的 Node API 會將 `asar` 壓縮檔視為許多虛擬目錄,將裡頭的檔案視為在檔案系統上的一般檔案。
例如,假設我們有一個 `example.asar` 壓縮檔在 `/path/to` 中:
```bash
$ asar list /path/to/example.asar
/app.js
/file.txt
/dir/module.js
/static/index.html
/static/main.css
/static/jquery.min.js
```
讀取一個在 `asar` 壓縮檔中的檔案:
```javascript
const fs = require('fs');
fs.readFileSync('/path/to/example.asar/file.txt');
```
列出所有在壓縮檔根目錄下的檔案:
```javascript
const fs = require('fs');
fs.readdirSync('/path/to/example.asar');
```
使用一個壓縮檔中的模組:
```javascript
require('/path/to/example.asar/dir/module.js');
```
你也可以利用 `BrowserWindow``asar` 壓縮檔中呈現一個網頁:
```javascript
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
在一個網頁中,壓縮檔中的檔案都可以透過 `file:` 這個協定被存取,如同 Node API`asar` 壓縮檔都被視為目錄。
例如,要透過 `$.get` 取得一個檔案:
```html
<script>
var $ = require('./jquery.min.js');
$.get('file:///path/to/example.asar/file.txt', function(data) {
console.log(data);
});
</script>
```
### 把一個 `asar` 壓縮檔視為一般檔案
在一些像是驗證 `asar` 壓縮檔檢查碼(checksum)的例子中,我們需要以檔案的方式讀取 `asar` 壓縮檔中的內容,為了達到這個目的,你可以使用內建的
`original-fs` 模組,它提供了沒有 `asar` 支援的原生 `fs` API:
```javascript
var originalFs = require('original-fs');
originalFs.readFileSync('/path/to/example.asar');
```
你也可以設定 `process.noAsar``true` 來關掉在 `fs` 模組中的 `asar` 支援:
```javascript
process.noAsar = true;
fs.readFileSync('/path/to/example.asar');
```
## Node API 上的限制
儘管我們盡可能的努力嘗試著使 Node API 中的 `asar` 壓縮檔像目錄一樣運作,還是有一些基於 Node API 低階本質的限制存在。
### 壓縮檔都是唯讀的
所有壓縮檔都無法被修改,因此所有可以修改檔案的 Node API 都無法與 `asar ` 壓縮檔一起運作。
### 使用中的目錄無法被設為壓縮檔中的目錄
儘管 `asar` 壓縮檔被視為目錄,卻並沒有真正的目錄在檔案系統中,所以你永遠無法將使用中的目錄設定成 `asar` 壓縮檔中的目錄,把他們以 `cwd` 選項的方式傳遞,對某些 API 也會造成錯誤。
### Extra Unpacking on Some APIs
Most `fs` APIs can read a file or get a file's information from `asar` archives
without unpacking, but for some APIs that rely on passing the real file path to
underlying system calls, Electron will extract the needed file into a
temporary file and pass the path of the temporary file to the APIs to make them
work. This adds a little overhead for those APIs.
APIs that requires extra unpacking are:
* `child_process.execFile`
* `child_process.execFileSync`
* `fs.open`
* `fs.openSync`
* `process.dlopen` - Used by `require` on native modules
### Fake Stat Information of `fs.stat`
The `Stats` object returned by `fs.stat` and its friends on files in `asar`
archives is generated by guessing, because those files do not exist on the
filesystem. So you should not trust the `Stats` object except for getting file
size and checking file type.
### Executing Binaries Inside `asar` Archive
There are Node APIs that can execute binaries like `child_process.exec`,
`child_process.spawn` and `child_process.execFile`, but only `execFile` is
supported to execute binaries inside `asar` archive.
This is because `exec` and `spawn` accept `command` instead of `file` as input,
and `command`s are executed under shell. There is no reliable way to determine
whether a command uses a file in asar archive, and even if we do, we can not be
sure whether we can replace the path in command without side effects.
## Adding Unpacked Files in `asar` Archive
As stated above, some Node APIs will unpack the file to filesystem when
calling, apart from the performance issues, it could also lead to false alerts
of virus scanners.
To work around this, you can unpack some files creating archives by using the
`--unpack` option, an example of excluding shared libraries of native modules
is:
```bash
$ asar pack app app.asar --unpack *.node
```
After running the command, apart from the `app.asar`, there is also an
`app.asar.unpacked` folder generated which contains the unpacked files, you
should copy it together with `app.asar` when shipping it to users.
[asar]: https://github.com/atom/asar