Browse Source

docs: add back docs about asar archives (#35563)

Cheng Zhao 2 years ago
parent
commit
748c6af61e
2 changed files with 176 additions and 0 deletions
  1. 1 0
      docs/README.md
  2. 175 0
      docs/tutorial/asar-archives.md

+ 1 - 0
docs/README.md

@@ -68,6 +68,7 @@ an issue:
   * [Mac App Store](tutorial/mac-app-store-submission-guide.md)
   * [Windows Store](tutorial/windows-store-guide.md)
   * [Snapcraft](tutorial/snapcraft.md)
+  * [ASAR Archives](tutorial/asar-archives.md)
 * [Updates](tutorial/updates.md)
 * [Getting Support](tutorial/support.md)
 

+ 175 - 0
docs/tutorial/asar-archives.md

@@ -0,0 +1,175 @@
+---
+title: ASAR Archives
+description: What is ASAR archive and how does it affect the application.
+slug: asar-archives
+hide_title: false
+---
+
+After creating an [application distribution](application-distribution.md), the
+app's source code are usually bundled into an [ASAR
+archive](https://github.com/electron/asar), which is a simple extensive archive
+format designed for Electron apps. By bundling the app we can mitigate issues
+around long path names on Windows, speed up `require` and conceal your source
+code from cursory inspection.
+
+The bundled app runs in a virtual file system and most APIs would just work
+normally, but for some cases you might want to work on ASAR archives explicitly
+due to a few caveats.
+
+## Using ASAR Archives
+
+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.
+
+### Node API
+
+With special patches in Electron, Node APIs like `fs.readFile` and `require`
+treat ASAR archives as virtual directories, and the files in it as normal
+files in the filesystem.
+
+For example, suppose we have an `example.asar` archive under `/path/to`:
+
+```sh
+$ 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:
+
+```javascript
+const fs = require('fs')
+fs.readFileSync('/path/to/example.asar/file.txt')
+```
+
+List all files under the root of the archive:
+
+```javascript
+const 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
+const { BrowserWindow } = require('electron')
+const win = new BrowserWindow()
+
+win.loadURL('file:///path/to/example.asar/static/index.html')
+```
+
+### Web API
+
+In a web page, files in an archive can be requested with the `file:` protocol.
+Like the Node API, ASAR archives are treated as directories.
+
+For example, to get a file with `$.get`:
+
+```html
+<script>
+let $ = require('./jquery.min.js')
+$.get('file:///path/to/example.asar/file.txt', (data) => {
+  console.log(data)
+})
+</script>
+```
+
+### Treating an ASAR archive as a Normal File
+
+For some cases like verifying the ASAR archive's checksum, we need to read the
+content of an ASAR archive as a file. For this purpose you can use the built-in
+`original-fs` module which provides original `fs` APIs without `asar` support:
+
+```javascript
+const originalFs = require('original-fs')
+originalFs.readFileSync('/path/to/example.asar')
+```
+
+You can also set `process.noAsar` to `true` to disable the support for `asar` in
+the `fs` module:
+
+```javascript
+const fs = require('fs')
+process.noAsar = true
+fs.readFileSync('/path/to/example.asar')
+```
+
+## Limitations of the Node API
+
+Even though we tried hard to make ASAR archives in the Node API work like
+directories as much as possible, there are still limitations due to the
+low-level nature of the Node API.
+
+### Archives Are Read-only
+
+The archives can not be modified so all Node APIs that can modify files will not
+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
+directories in ASAR archives. Passing them as the `cwd` option of some APIs
+will also cause errors.
+
+### 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 to ASAR archives
+
+As stated above, some Node APIs will unpack the file to the filesystem when
+called. Apart from the performance issues, various anti-virus scanners might
+be triggered by this behavior.
+
+As a workaround, you can leave various files unpacked using the `--unpack` option.
+In the following example, shared libraries of native Node.js modules will not be
+packed:
+
+```sh
+$ asar pack app app.asar --unpack *.node
+```
+
+After running the command, you will notice that a folder named `app.asar.unpacked`
+was created together with the `app.asar` file. It contains the unpacked files
+and should be shipped together with the `app.asar` archive.