2014-09-29 13:34:54 +00:00
|
|
|
# Application packaging
|
2014-09-29 15:05:02 +00:00
|
|
|
|
|
|
|
To protect your app's resources and source code from the users, you can choose
|
2014-10-14 01:16:22 +00:00
|
|
|
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
|
|
|
|
|
2014-10-14 01:16:22 +00:00
|
|
|
An [asar][asar] archive is a simple tar-like format that concatenates files
|
2014-09-29 15:05:02 +00:00
|
|
|
into a single file, atom-shell can read arbitrary file in it without unpacking
|
|
|
|
the whole file.
|
|
|
|
|
2014-10-14 01:16:22 +00:00
|
|
|
Following is the steps to package your app into an `asar` archive:
|
2014-09-29 15:05:02 +00:00
|
|
|
|
2014-10-14 01:16:22 +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
|
|
|
|
|
|
|
|
In atom-shell there are two sets of APIs: Node APIs provided by Node.js, and Web
|
2014-10-14 01:16:22 +00:00
|
|
|
APIs provided by Chromium. Both APIs support reading files from `asar` archives.
|
2014-09-29 15:05:02 +00:00
|
|
|
|
|
|
|
### Node API
|
|
|
|
|
|
|
|
With special patches in atom-shell, Node APIs like `fs.readFile` and `require`
|
|
|
|
treat `asar` archives as virtual directories, and the files in it as normal
|
2014-10-14 01:16:22 +00:00
|
|
|
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
|
|
|
|
```
|
|
|
|
|
2014-10-14 01:16:22 +00:00
|
|
|
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');
|
|
|
|
```
|
|
|
|
|
2014-10-14 01:16:22 +00:00
|
|
|
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');
|
|
|
|
```
|
|
|
|
|
|
|
|
### 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-10-14 01:16:22 +00:00
|
|
|
You can also display a web page in an `asar` archive with `BrowserWindow`:
|
2014-09-29 15:05:02 +00:00
|
|
|
|
|
|
|
```javascript
|
|
|
|
var BrowserWindow = require('browser-window');
|
|
|
|
var win = new BrowserWindow({width: 800, height: 600});
|
2015-02-01 02:48:11 +00:00
|
|
|
win.loadUrl('file:///path/to/example.asar/static/index.html');
|
2014-09-29 15:05:02 +00:00
|
|
|
```
|
|
|
|
|
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
|
|
|
|
|
2014-10-14 01:16:22 +00:00
|
|
|
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
|
2014-10-14 01:16:22 +00:00
|
|
|
low-level nature of the Node API.
|
2014-09-29 15:05:02 +00:00
|
|
|
|
|
|
|
### Archives are read only
|
|
|
|
|
2014-10-14 01:16:22 +00:00
|
|
|
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
|
2014-10-14 01:16:22 +00:00
|
|
|
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
|
|
|
|
underlying system calls, atom-shell 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.fork`
|
|
|
|
* `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`
|
2014-10-14 01:16:22 +00:00
|
|
|
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.
|
|
|
|
|
|
|
|
[asar]: https://github.com/atom/asar
|