From 6fc5ff77c15383d47bbde51261b14a1c4161d5a4 Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 2 Dec 2020 08:52:12 +0200 Subject: [PATCH] docs: app distribution page (#26239) * docs: first draft of the app distribution page * docs: second iteration of the app distribution page. Fixed mentions * docs: third iteration of the app distribution page. Fixed mentions * docs: reworked app distribution page according to mentions * docs: minor fixes to the app distribution page according to mentions --- docs/README.md | 5 - docs/tutorial/application-distribution.md | 118 +++++-------- docs/tutorial/application-packaging.md | 194 ---------------------- 3 files changed, 44 insertions(+), 273 deletions(-) delete mode 100644 docs/tutorial/application-packaging.md diff --git a/docs/README.md b/docs/README.md index 7fb1fb9afc86..abe6a64634d5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -91,11 +91,6 @@ These individual tutorials expand on topics discussed in the guide above. * Electron Releases & Developer Feedback * [Versioning Policy](tutorial/electron-versioning.md) * [Release Timelines](tutorial/electron-timelines.md) -* [Packaging App Source Code with asar](tutorial/application-packaging.md) - * [Generating asar Archives](tutorial/application-packaging.md#generating-asar-archives) - * [Using asar Archives](tutorial/application-packaging.md#using-asar-archives) - * [Limitations](tutorial/application-packaging.md#limitations-of-the-node-api) - * [Adding Unpacked Files to asar Archives](tutorial/application-packaging.md#adding-unpacked-files-to-asar-archives) * [Testing Widevine CDM](tutorial/testing-widevine-cdm.md) --- diff --git a/docs/tutorial/application-distribution.md b/docs/tutorial/application-distribution.md index b74f6a1956eb..5bc3a6a67d44 100644 --- a/docs/tutorial/application-distribution.md +++ b/docs/tutorial/application-distribution.md @@ -1,25 +1,38 @@ # Application Distribution -To distribute your app with Electron, you need to package and rebrand it. The easiest way to do this is to use one of the following third party packaging tools: +## Overview + +To distribute your app with Electron, you need to package and rebrand it. +To do this, you can either use specialized tooling or manual approaches. + +## With tooling + +You can use the following tools to distribute your application: * [electron-forge](https://github.com/electron-userland/electron-forge) * [electron-builder](https://github.com/electron-userland/electron-builder) * [electron-packager](https://github.com/electron/electron-packager) -These tools will take care of all the steps you need to take to end up with a distributable Electron applications, such as packaging your application, rebranding the executable, setting the right icons and optionally creating installers. +These tools will take care of all the steps you need to take to end up with a +distributable Electron application, such as bundling your application, +rebranding the executable, and setting the right icons. + +You can check the example of how to package your app with `electron-forge` in +our [Quick Start Guide](quick-start.md#package-and-distribute-the-application). ## Manual distribution -You can also choose to manually get your app ready for distribution. The steps needed to do this are outlined below. +### With prebuilt binaries -To distribute your app with Electron, you need to download Electron's [prebuilt +To distribute your app manually, you need to download Electron's [prebuilt binaries](https://github.com/electron/electron/releases). Next, the folder containing your app should be named `app` and placed in Electron's resources -directory as shown in the following examples. Note that the location of -Electron's prebuilt binaries is indicated with `electron/` in the examples -below. +directory as shown in the following examples. -On macOS: +> *NOTE:* the location of Electron's prebuilt binaries is indicated +with `electron/` in the examples below. + +*On macOS:* ```plaintext electron/Electron.app/Contents/Resources/app/ @@ -28,7 +41,7 @@ electron/Electron.app/Contents/Resources/app/ └── index.html ``` -On Windows and Linux: +*On Windows and Linux:* ```plaintext electron/resources/app @@ -37,47 +50,44 @@ electron/resources/app └── index.html ``` -Then execute `Electron.app` (or `electron` on Linux, `electron.exe` on Windows), -and Electron will start as your app. The `electron` directory will then be -your distribution to deliver to final users. +Then execute `Electron.app` on macOS, `electron` on Linux, or `electron.exe` +on Windows, and Electron will start as your app. The `electron` directory +will then be your distribution to deliver to users. -## Packaging Your App into a File +### With an app source code archive -Apart from shipping your app by copying all of its source files, you can also -package your app into an [asar](https://github.com/electron/asar) archive to avoid -exposing your app's source code to users. +Instead of from shipping your app by copying all of its source files, you can +package your app into an [asar] archive to improve the performance of reading +files on platforms like Windows, if you are not already using a bundler such +as Parcel or Webpack. To use an `asar` archive to replace the `app` folder, you need to rename the archive to `app.asar`, and put it under Electron's resources directory like below, and Electron will then try to read the archive and start from it. -On macOS: +*On macOS:* ```plaintext electron/Electron.app/Contents/Resources/ └── app.asar ``` -On Windows and Linux: +*On Windows and Linux:* ```plaintext electron/resources/ └── app.asar ``` -More details can be found in [Application packaging](application-packaging.md). +You can find more details on how to use `asar` in the +[`electron/asar` repository][asar]. -## Rebranding with Downloaded Binaries +### Rebranding with downloaded binaries After bundling your app into Electron, you will want to rebrand Electron before distributing it to users. -### Windows - -You can rename `electron.exe` to any name you like, and edit its icon and other -information with tools like [rcedit](https://github.com/electron/rcedit). - -### macOS +#### macOS You can rename `Electron.app` to any name you want, and you also have to rename the `CFBundleDisplayName`, `CFBundleIdentifier` and `CFBundleName` fields in the @@ -104,60 +114,20 @@ MyApp.app/Contents    └── MyApp Helper ``` -### Linux +#### Windows + +You can rename `electron.exe` to any name you like, and edit its icon and other +information with tools like [rcedit](https://github.com/electron/rcedit). + +#### Linux You can rename the `electron` executable to any name you like. -## Rebranding by Rebuilding Electron from Source +### Rebranding by rebuilding Electron from source It is also possible to rebrand Electron by changing the product name and building it from source. To do this you need to set the build argument corresponding to the product name (`electron_product_name = "YourProductName"`) in the `args.gn` file and rebuild. -### Creating a Custom Electron Fork - -Creating a custom fork of Electron is almost certainly not something you will -need to do in order to build your app, even for "Production Level" applications. -Using a tool such as `electron-packager` or `electron-forge` will allow you to -"Rebrand" Electron without having to do these steps. - -You need to fork Electron when you have custom C++ code that you have patched -directly into Electron, that either cannot be upstreamed, or has been rejected -from the official version. As maintainers of Electron, we very much would like -to make your scenario work, so please try as hard as you can to get your changes -into the official version of Electron, it will be much much easier on you, and -we appreciate your help. - -#### Creating a Custom Release with surf-build - -1. Install [Surf](https://github.com/surf-build/surf), via npm: - `npm install -g surf-build@latest` - -2. Create a new S3 bucket and create the following empty directory structure: - - ```sh - - electron/ - - symbols/ - - dist/ - ``` - -3. Set the following Environment Variables: - - * `ELECTRON_GITHUB_TOKEN` - a token that can create releases on GitHub - * `ELECTRON_S3_ACCESS_KEY`, `ELECTRON_S3_BUCKET`, `ELECTRON_S3_SECRET_KEY` - - the place where you'll upload Node.js headers as well as symbols - * `ELECTRON_RELEASE` - Set to `true` and the upload part will run, leave unset - and `surf-build` will do CI-type checks, appropriate to run for every - pull request. - * `CI` - Set to `true` or else it will fail - * `GITHUB_TOKEN` - set it to the same as `ELECTRON_GITHUB_TOKEN` - * `SURF_TEMP` - set to `C:\Temp` on Windows to prevent path too long issues - * `TARGET_ARCH` - set to `ia32` or `x64` - -4. In `script/upload.py`, you _must_ set `ELECTRON_REPO` to your fork (`MYORG/electron`), - especially if you are a contributor to Electron proper. - -5. `surf-build -r https://github.com/MYORG/electron -s YOUR_COMMIT -n 'surf-PLATFORM-ARCH'` - -6. Wait a very, very long time for the build to complete. +[asar]: https://github.com/electron/asar diff --git a/docs/tutorial/application-packaging.md b/docs/tutorial/application-packaging.md deleted file mode 100644 index e0c782fe7d1e..000000000000 --- a/docs/tutorial/application-packaging.md +++ /dev/null @@ -1,194 +0,0 @@ -# Application Packaging - -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. - -Most users will get this feature for free, since it's supported out of the box -by [`electron-packager`][electron-packager], [`electron-forge`][electron-forge], -and [`electron-builder`][electron-builder]. If you are not using any of these -tools, read on. - -## Generating `asar` Archives - -An [asar][asar] archive is a simple tar-like format that concatenates files -into a single file. Electron can read arbitrary files from it without unpacking -the whole file. - -Steps to package your app into an `asar` archive: - -### 1. Install the asar Utility - -```sh -$ npm install -g asar -``` - -### 2. Package with `asar pack` - -```sh -$ asar pack your-app app.asar -``` - -## 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 - -``` - -### 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. - -[asar]: https://github.com/electron/asar -[electron-packager]: https://github.com/electron/electron-packager -[electron-forge]: https://github.com/electron-userland/electron-forge -[electron-builder]: https://github.com/electron-userland/electron-builder