Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
with:
cname: js.electronforge.io
defaultBranch: main
docsPath: api-docs
noCommit: true
showUnderscoreFiles: true
env:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
.nyc_output
*.lcov
/coverage
api-docs
dist
docs
doc
node_modules
lerna-debug.log
Expand Down
2 changes: 1 addition & 1 deletion .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
],
"ignorePatterns": [
"**/.claude/**",
"api-docs/",
"dist",
"docs/",
"node_modules",
"*.d.ts",
"packages/*/*/doc",
Expand Down
7 changes: 7 additions & 0 deletions docs/_partials/static-file-auto-updates.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
:::tip
**Static file auto-updates with DMG distributions**

The [Squirrel.Mac](https://github.com/Squirrel/Squirrel.mac) implementation behind Electron's `autoUpdater` module on macOS supports static file auto-updates from the ZIP artifacts uploaded to your cloud storage [Publishers](../config/publishers/index.md).

If you want to distribute a DMG that supports static file auto-updates, make sure to also make a [ZIP](../config/makers/zip.md) target and follow the [Auto updating from S3](../config/publishers/s3.mdx#auto-updating-from-s3) instructions to configure updates.
:::
35 changes: 35 additions & 0 deletions docs/advanced/auto-update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
description: Set up automatic updates for your Electron application
---

# Auto Update

Setting up Auto Updates in your app with Electron Forge is mostly the same process [as described in the Electron docs](https://electronjs.org/docs/tutorial/updates). Forge enhances your workflow by publishing your app to the right place for you. There are three main ways you can do auto updates.

:::warning
Note that having a [signed](../guides/code-signing/code-signing-macos.md) application is a pre-requisite for using auto updates on macOS.
:::

## Open source apps: update.electronjs.org

Open source apps hosted on GitHub can use a free auto update service from the Electron team, [update.electronjs.org](auto-update.md#open-source-apps-updateelectronjsorg). To use this module with Forge, set up the [GitHub Publisher](../config/publishers/github.md) and add the [`update-electron-app`](https://github.com/electron/update-electron-app) module to your app.

This setup is going to be around 2 lines of code and a few lines of configuration. It is by far the easiest way to set up auto updates if you're an open source app.

## Hosting updates on static storage providers

If you are using any of Forge's built-in Publishers that upload your artifacts to static storage, they each have a documentation section on how to configure your app to auto update using those uploaded artifacts. Check out each of the options:

* [Amazon S3](../config/publishers/s3.mdx#auto-updating-from-s3)
* Google Cloud Storage _(Coming Soon)_

## Hosting your own update server

If you're not open source or you want slightly more control over your update service (like percentage based rollouts, or more release channels) you can host your own update server such as [`nucleus`](https://github.com/atlassian/nucleus) or [`nuts`](https://github.com/GitbookIO/nuts). See the full list of known Electron update servers in the [Electron's Updating Applications docs](https://electronjs.org/docs/tutorial/updates#deploying-an-update-server).

Each update server will have their own configuration for your actual app, but publishing should be done from Forge for most of them:

* `nucleus` - Use the [Nucleus](../config/publishers/nucleus.md) publish target
* `nuts` - Use the [GitHub](../config/publishers/github.md) publish target
* `electron-release-server` - Use the [Electron Release Server](../config/publishers/electron-release-server.md) publish target
* `hazel` - Use the [GitHub](../config/publishers/github.md) publish target
64 changes: 64 additions & 0 deletions docs/advanced/debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Debugging

In Electron apps, the main and renderer processes have different debugging mechanisms:

* Renderer processes can be debugged using Chromium DevTools.
* The main process can be debugged via the `--inspect` and `--inspect-brk` command line flags.

This guide goes over Forge-specific ways of debugging the main process through the command line or with a code editor.

:::info
Each section in this guide assumes your `package.json` has a `"start": "electron-forge start"` script.
:::

For more general information on debugging Electron apps, see the [main Electron docs on Application Debugging](https://www.electronjs.org/docs/latest/tutorial/application-debugging#renderer-process).

## Debugging on the command line

You can specify the `--inspect-electron` flag when running `electron-forge start`. Internally, this will activate the [Electron `--inspect`flag](http://electronjs.org/docs/tutorial/debugging-main-process#--inspectport), and the main process will listen for a debugging client on port 5858.

```bash
npm run start -- --inspect-electron
```

Once your app is active, open [`chrome://inspect`](chrome://inspect) in any Chromium-based browser to attach a debugger to the main process of your app.

:::info
To add a breakpoint at the first line of execution when debugging, you can use Forge's `--inspect-brk-electron` flag instead.
:::

## Debugging with VS Code

To debug the main process through VS Code, add the following [Node.js launch configuration](https://code.visualstudio.com/docs/nodejs/nodejs-debugging):

```json5 title=".vscode/launch.json"
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Electron Main",
"runtimeExecutable": "${workspaceFolder}/node_modules/@electron-forge/cli/script/vscode.sh",
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/@electron-forge/cli/script/vscode.cmd"
},
// runtimeArgs will be passed directly to your Electron application
"runtimeArgs": [
"foo",
"bar"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}
```

Once this configuration is added, launch the app via VS Code's Run and Debug view to start debugging.

## Debugging with WebStorm or Other Jetbrains IDEs

1. Access the `Run > Debug...` menu and select the `Edit Configurations...` option to open the `Run/Debug Configurations` window.
2. Click on the `Add new configuration` button (the `+` icon) in the upper-left corner and select the `npm` template.
3. In the `Scripts` dropdown menu, select `start`.
4. Click on `Debug` to start debugging your app.
9 changes: 9 additions & 0 deletions docs/advanced/extending-electron-forge/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Extending Electron Forge

Electron Forge is designed to be easily extendable by third parties with whatever build logic you need. The build flow for Electron Forge is split into two main sections, `make` and `publish`, and you can define custom targets for each of those commands. For everything else we have a Plugin API which allows you to hook into pretty much any part of Forge's standard build process and do whatever you want.

To briefly explain some terms:

* `maker`: A tool that takes a packaged Electron application and outputs a certain kind of distributable
* `publisher`: A tool that takes distributables and "publishes" \(normally just uploads\) them somewhere \(for example, GitHub releases\)
* `plugin`: A tool that hooks into Forge's internals and can inject logic into your build process
46 changes: 46 additions & 0 deletions docs/advanced/extending-electron-forge/writing-makers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Writing Makers

An Electron Forge Maker has to export a single class that extends our base maker. The base maker can be depended on by installing`@electron-forge/maker-base`.

The `MakerBase` class has some helper methods for your convenience. Check out the interface of [`MakerBase`](https://js.electronforge.io/classes/_electron_forge_maker_base.MakerBase.html) for more advanced API details.

| Method | Description |
| :--- | :--- |
| `ensureDirectory(path)` | Ensures the directory exists and is forced to be empty. This is a destructive operation. |
| `ensureFile(path)` | Ensures the path to the file exists and the file does not exist, if the file exists it is deleted and the path created. |
| `isInstalled(moduleName)` | Checks if the given module is installed, used for testing if optional dependencies are installed or not. |

Your maker **must** implement two methods:

### `isSupportedOnCurrentPlatform(): boolean`

This method must synchronously return a boolean indicating whether or not this maker can run on the current platform. Normally this is just a `process.platform` check but it can be a deeper check for dependencies like `fake-root` or other required external build tools.

If the issue is a missing dependency you should log out a **helpful** error message telling the developer exactly what is missing and if possible how to get it.

```javascript
export default class MyMaker extends MakerBase {
isSupportedOnCurrentPlatform () {
return process.platform === 'linux' && this.isFakeRootInstalled();
}

isFakeRootInstalled () { /* ... */ }
}
```

### `make(options: MakerOptions): Promise<string[]>`

Makers must implement this method and return an array of **absolute** paths to the artifacts this maker generated. If an error occurs, reject the promise and Electron Forge will stop the `make` process.

The `config` for the maker will be available on `this.config`.

The options object is documented in [`MakerOptions`](https://js.electronforge.io/interfaces/_electron_forge_maker_base.MakerOptions.html).

```javascript
export default class MyMaker extends MakerBase {
async make (opts) {
const pathToMagicInstaller = await makeMagicInstaller(opts.dir);
return [pathToMagicInstaller];
}
}
```
44 changes: 44 additions & 0 deletions docs/advanced/extending-electron-forge/writing-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Writing Plugins

An Electron Forge Plugin has to export a single class that extends our base plugin. The base plugin can be depended on by installing`@electron-forge/plugin-base`. It can implement two methods, neither are required.

### `getHooks(): ForgeMultiHookMap`

If implemented this method will be once during plugin initialization inside Forge, this method is called only once and shouldn't result in any side effects being executed. You must return an object in a similar format to `forgeConfig.hooks`. i.e. an object map between hook names and an array of hook functions.

The possible hook names and the parameters passed to the hook function you return are documented over in the [Configuration](../../config/configuration.mdx) section of the docs.

```javascript
export default class MyPlugin extends PluginBase {
getHooks () {
return {
prePackage: [this.prePackage]
};
}

prePackage () {
console.log('running prePackage hook');
}
}
```

### `startLogic(startOpts: StartOptions): Promise<ChildProcess | false>`

If implemented, this method will be called every time the user runs `electron-forge start`, if you return a `ChildProcess` you can override the built in start logic and Electron Forge will not spawn it's own process, rather it will watch the one you returned. If you return `false` forge will spawn Electron itself but you could still run custom logic such as started compilation for code or downloading certain binaries before the app starts.

Please note that overriding the start logic here only works in **development** if you want to change how an app runs once packaged you will need to use a build hook to inject code into the packaged app.

:::info
`StartOptions`is explained further [in the API docs](https://js.electronforge.io/interfaces/\_electron\_forge\_shared\_types.StartOptions.html).
:::

```javascript
export default class MyPlugin extends Pluginbase {
async startLogic (opts) {
await this.compileMainProcess();
return null;
}

compileMainProcess () { /* ... */ }
}
```
28 changes: 28 additions & 0 deletions docs/advanced/extending-electron-forge/writing-publishers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Writing Publishers

An Electron Forge Publisher has to export a single class that extends the base publisher. The base plugin can be depended on by installing`@electron-forge/publisher-base`.

Check out the interface of [`PublisherBase`](https://js.electronforge.io/modules/_electron_forge_publisher_base.html) for more advanced API details.

The publisher **must** implement one method:

### `publish(options: PublisherOptions): Promise<void>`

Publishers must implement this method to publish the artifacts returned from make calls. If any errors occur you must throw them, failing silently or simply logging will not propagate issues up to Forge.

Please note for a given version, publish will be called multiple times, once for each set of "platform" and "arch". This means if you are publishing `darwin` and `win32` artifacts to somewhere like GitHub on the first publish call, you will have to create the version on GitHub and the second call will just be appending files to the existing version. Your `publish` implementation will not be aware that another call is coming, however it must just be able to handle this case.

The `config` for the publisher will be available on `this.config`.

The options object is documented in [`PublisherOptions`](https://js.electronforge.io/interfaces/_electron_forge_publisher_base.PublisherOptions.html).

```javascript
export default class MyPublisher extends PublisherBase {
async publish (opts) {
for (const result of opts.makeResults) {
await createVersionIfNotExists();
await uploadDistributable(result);
}
}
}
```
14 changes: 14 additions & 0 deletions docs/advanced/extending-electron-forge/writing-templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
description: How to write custom templates for Electron Forge.
---

# Writing Templates

Templates in Electron Forge implement the `ForgeTemplate` interface, namely:

* `requiredForgeVersion` _(required)_ - the semantic version range of Electron Forge versions that this template supports. For example, `^6.0.0-beta.1`
* `dependencies` _(optional)_ - a list of package identifiers that you pass to a package manager (which may include a version range) to add to the `dependencies` field in `package.json`. For example, `jquery` or `jquery@^3.0.0`
* `devDependencies` _(optional)_ - a list of package identifiers that you pass to a package manager (which may include a version range) to add to the `devDependencies` field in `package.json`. For example, `eslint` or `eslint@^7.0.0`
* `initializeTemplate` _(optional)_ - an `async` function that allows the template to perform custom actions, for example copying files from a `tmpl` folder into the new app. The exact function signature is defined in the shared types package.

To use the custom template, run the [init](../../cli.md#init) command and point the template at the file that contains the `ForgeTemplate` implementation.
Loading