electron/docs/tutorial/application-packaging.md

165 lines
4.8 KiB
Markdown
Raw Normal View History

2014-09-29 13:34:54 +00:00
# Application packaging
2014-09-29 15:05:02 +00:00
To mitigate [issues](https://github.com/joyent/node/issues/6960) around long path names on Windows, slightly speed up `require` and conceal your source code from cursory inspection you can choose
to package your app into an [asar][asar] archive with little changes to your
source code.
2014-09-29 15:05:02 +00:00
## Generating `asar` archive
An [asar][asar] archive is a simple tar-like format that concatenates files
2015-04-16 03:31:12 +00:00
into a single file, Electron can read arbitrary files from it without unpacking
2014-09-29 15:05:02 +00:00
the whole file.
Following is the steps to package your app into an `asar` archive:
2014-09-29 15:05:02 +00:00
### 1. Install the asar utility
2014-09-29 15:05:02 +00:00
```bash
$ npm install -g asar
```
### 2. Package with `asar pack`
```bash
$ asar pack your-app app.asar
```
## Using `asar` archives
2015-04-16 03:31:12 +00:00
In Electron there are two sets of APIs: Node APIs provided by Node.js, and Web
APIs provided by Chromium. Both APIs support reading files from `asar` archives.
2014-09-29 15:05:02 +00:00
### Node API
2015-04-16 03:31:12 +00:00
With special patches in Electron, Node APIs like `fs.readFile` and `require`
2014-09-29 15:05:02 +00:00
treat `asar` archives as virtual directories, and the files in it as normal
files in the filesystem.
2014-09-29 15:05:02 +00:00
For example, suppose we have an `example.asar` archive under `/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
```
Read a file in the `asar` archive:
2014-09-29 15:05:02 +00:00
```javascript
var fs = require('fs');
fs.readFileSync('/path/to/example.asar/file.txt');
```
List all files under the root of the archive:
2014-09-29 15:05:02 +00:00
```javascript
var fs = require('fs');
fs.readdirSync('/path/to/example.asar');
```
Use a module from the archive:
```javascript
require('/path/to/example.asar/dir/module.js');
```
You can also display a web page in an `asar` archive with `BrowserWindow`:
```javascript
var BrowserWindow = require('browser-window');
var win = new BrowserWindow({width: 800, height: 600});
win.loadUrl('file:///path/to/example.asar/static/index.html');
```
2014-09-29 15:05:02 +00:00
### Web API
2015-02-01 02:48:11 +00:00
In a web page, files in archive can be requested with the `file:` protocol. Like
the Node API, `asar` archives are treated as directories.
2014-09-29 15:05:02 +00:00
For example, to get a file with `$.get`:
```html
<script>
var $ = require('./jquery.min.js');
2015-02-01 02:48:11 +00:00
$.get('file:///path/to/example.asar/file.txt', function(data) {
2014-09-29 15:05:02 +00:00
console.log(data);
});
</script>
```
2014-11-12 03:58:03 +00:00
### Treating `asar` archive as normal file
For some cases like verifying the `asar` archive's checksum, we need to read the
content of `asar` archive as file. For this purpose you can use the built-in
`original-fs` module which provides original `fs` APIs without `asar` support:
```javascript
var originalFs = require('original-fs');
originalFs.readFileSync('/path/to/example.asar');
```
2014-09-29 15:05:02 +00:00
## Limitations on Node API
Even though we tried hard to make `asar` archives in the Node API work like
2014-09-29 15:05:02 +00:00
directories as much as possible, there are still limitations due to the
low-level nature of the Node API.
2014-09-29 15:05:02 +00:00
### Archives are read only
The archives can not be modified so all Node APIs that can modify files will not
2014-09-29 15:05:02 +00:00
work with `asar` archives.
### Working directory can not be set to directories in archive
Though `asar` archives are treated as directories, there are no actual
directories in the filesystem, so you can never set the working directory to
2014-09-29 15:05:02 +00:00
directories in `asar` archives, passing them to `cwd` option of some APIs will
also cause errors.
### Extra unpacking on some APIs
Most `fs` APIs can read file or get file's information from `asar` archives
without unpacking, but for some APIs that rely on passing the real file path to
2015-04-16 03:31:12 +00:00
underlying system calls, Electron will extract the needed file into a
2014-09-29 15:05:02 +00:00
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`
* `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
2014-09-29 15:05:02 +00:00
filesystem. So you should not trust the `Stats` object except for getting file
size and checking file type.
## 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.
2015-03-20 13:32:10 +00:00
2014-09-29 15:05:02 +00:00
[asar]: https://github.com/atom/asar