Build Angular Desktop Apps With Electron

Based on Jeff Delaney post. You can also check the video lesson on youtube and the original source code on github.

You can also find my source code on github.

Generate the angular app

You can follow the Angular – QuickStart or just do these steps:

npm install -g @angular/cli
ng new angular-electron
cd angular-electron

Update base tag on index.html

The generated root page in Angular points the base href to / – this will cause problems with Electron later on, so let’s update it now.

<base href="./">

Install Electron

npm install electron --save-dev

Configure Electron

Create a new file named main.js in the root of your project – this is the Electron NodeJS backend. This is the entry point for Electron and defines how our desktop app will react to various events performed via the desktop operating system.

const { app, BrowserWindow } = require('electron')

let win;

function createWindow () {
  // Create the browser window.
  win = new BrowserWindow({
    width: 600, 
    height: 600,
    backgroundColor: '#ffffff',
    icon: `file://${__dirname}/dist/assets/logo.png`
  })


  win.loadURL(`file://${__dirname}/dist/index.html`)

  //// uncomment below to open the DevTools.
  // win.webContents.openDevTools()

  // Event when the window is closed.
  win.on('closed', function () {
    win = null
  })
}

// Create window on electron intialization
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {

  // On macOS specific close process
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // macOS specific close process
  if (win === null) {
    createWindow()
  }
})

The createWindow function defines the properties of the program window that the user will see.

Notice we are loading the window by pointing it to the index.html file in the dist/ folder. Do NOT confuse this with the index file in the src/ folder. At this point, this file does not exist, but it will be created automatically in the next step by running ng build –prod

Custom Build Command

The deployed desktop app will be an Angular AOT build – this happens by default when you run ng build –prod. It’s useful to have a command that will run an AOT production build and start Electron at the same time. This can be easily configured in the package.json file.

{
  "name": "angular-electron",
  "version": "0.0.0",
  "license": "MIT",
  "main": "main.js", // <-- add this
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "electron": "electron .", // <-- add this to run electron 
    "electron-build": "ng build --prod && electron ." // <-- add this to build app in prod with AOT and then run electron 
  },
  // ...omitted
}

Run the electron app

You can run your angular app as an native desktop app with the following command.

npm run electron-build

At this point, you can run the command (it will take a few seconds) and it will create the dist/ folder and will automatically bring up a window on your operating system with default Angular app.

This setup does not support hot code reloads. Whenever you change some Angular code, you need to rerun the electron-build command. It is possible to setup hot reloads by pointing the window to a remote URL (such as https://localhost:4200) and running npm start in a separate terminal and then running npm run electron.

Build you Angular App

This section is up to you, if you want something ready, check the Jeff’s post.

Packaging for Desktop Operating Systems

This section is slightly different from the original post, because I had to add –no-prune and a series of –ignore to let electron-packager works as expected.

The electron packager tool will allow to package our code into an executable for desktop platforms – including Windows (win32), MacOS (darwin), and Linux. Keep in mind, there are several other electron packaging tools that might better fit your needs.

npm install electron-packager -g
npm install electron-packager --save-dev

Build an executable for Windows:

electron-packager . --platform=win32 --no-prune --ignore=/node_modules --ignore=/e2e --ignore=/src

Build an executable for MaxOS:

electron-packager . --platform=darwin --no-prune --ignore=/node_modules --ignore=/e2e --ignore=/src

The you can add an npm script electron-package-win to easy package for Windows:

{
 "name": "angular-electron",
 "version": "0.0.0",
 "license": "MIT",
 "main": "main.js",
 "scripts": {
 "ng": "ng",
 "start": "ng serve",
 "build": "ng build --prod",
 "test": "ng test",
 "lint": "ng lint",
 "e2e": "ng e2e",
 "electron": "electron .",
 "electron-build": "ng build --prod && electron .",
 "electron-package-win": "ng build --prod && electron-packager . --no-prune --ignore=/node_modules --ignore=/e2e --ignore=/src --overwrite" // <-- add this script
 }
 // ...omitted
}

Then call it like this:

npm run electron-package-win