Angular 4 + Electron - How to run application and watch for changes (live reload)
Asked Answered
K

6

9

I am creating an Electron application using Angular 4. How can i set it up so that it watches for any changes and live reloads it.

package.json

{
  "name": "angular-electron",
  "version": "0.0.0",
  "license": "MIT",
  "main": "main.js",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "electron": "electron .",
    "electron-build": "ng build --prod && electron ."
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.2.4",
    "@angular/common": "^4.2.4",
    "@angular/compiler": "^4.2.4",
    "@angular/core": "^4.2.4",
    "@angular/forms": "^4.2.4",
    "@angular/http": "^4.2.4",
    "@angular/platform-browser": "^4.2.4",
    "@angular/platform-browser-dynamic": "^4.2.4",
    "@angular/router": "^4.2.4",
    "angular-svg-round-progressbar": "^1.1.0",
    "bulma": "^0.5.3",
    "core-js": "^2.4.1",
    "rxjs": "^5.4.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "1.4.1",
    "@angular/compiler-cli": "^4.2.4",
    "@angular/language-service": "^4.2.4",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.1.1",
    "electron": "^1.7.6",
    "electron-packager": "^9.1.0",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.3.2",
    "typescript": "~2.3.3"
  }
}

electron

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()
  }
})

thanks.

Currently, i build my application every time using the following command

ng build --prod && electron .

This gets tiring, so i want to be able to build run one command so it watches for changes and live reloads.

Katharinekatharsis answered 2/10, 2017 at 20:18 Comment(1)
Can you just add --watch to your build command 'ng build --watch --prod && electron .'Virga
B
3

With the following you can serve the application using ng serve wich is faster for development while automatically reloading every time there's a change to your code.

Install electron-reloader and concurrently

npm install --save-dev electron-reloader concurrently

In your main.js initialize electron reloader and load the app from URL (we do this because the app is being served via the local development server from memory and it's not on a physical path)

try {
  require('electron-reloader')(module)
} catch {}

//...

mainWindow.loadURL("http://localhost:4200/")

Lastly use concurrently to run both ng serve and electron .

"electron-dev": "concurrently \"ng serve\" \"electron .\""

You should be able to see an empty electron app window, but once the development server is ready you can press Ctrl+R or change something in the code to see your app. From now on any change to the code will force a reload on the app, just as if you were working on a browser.

Bonnee answered 21/11, 2023 at 22:48 Comment(0)
B
2

You can use electron-reload for hot module reload. It listens on file changes and reloads the electron app.

Simply add it to the devDependencies in your package.json.

Then, you have to add it to your main.ts:

import { app, BrowserWindow, Menu } from 'electron';

let win, serve;
const args = process.argv.slice(1);
serve = args.some(val => val === '--serve');

if (serve) {
  require('electron-reload')(__dirname, {});
}

Then add a command to your package json

"start": "webpack --watch",
"serve": "npm run build:main && electron ./dist --serve",
"build:main": "tsc main.ts --outDir dist && copyfiles package.json dist && cd dist && npm install --prod"

where build:main is your build script to compile your project. This compiles all Typescript files and puts them into the dist folder. Afterwards, it runs npm install to download and install modules from NPM.

You need the module-bundler Webpack for this to run. Install it with

npm install --save-dev webpack

First, in a console run npm start. Afterwards, in a second console executenpm run serve. Now, it listens for changes and recompiles on file changes.

tsc stands for TypeScript compiler. If you're using tsc as a node module, make sure its installed:

npm install -g typescript

I use it currently for a project with the same setup (Angular 4, Electron) and it works perfectly.

Bicarbonate answered 3/10, 2017 at 9:50 Comment(13)
Hey, can you provide a snippet of your package.json file so i can see it clearly/? including build:main. And im also confused by ./dist folder. I dont have that in my application.Manhunt
Here is the build:main command "build:main": "tsc main.ts --outDir dist && copyfiles package.json dist && cd dist && npm install --prod"Bicarbonate
I tried this again, but in your npm start youre doing webpack --watch. But you have not provided information about your webpack....Manhunt
@MatthiasSommer, I tried your instructions but like KHAN says when I run first nom start I am already getting an error message about the web pack ...Cleisthenes
Do you have webpack in your devDependencies? such as "webpack": "3.8.1"Bicarbonate
@MatthiasSommer, no. what to install and setup to get it to work?Cleisthenes
@Cleisthenes Run npm install --save-dev webpackBicarbonate
just fyi, i never did get this working. Just started using ng serve --watch in browser and occasionally build it, to check electron. What you see in chrome is what you'll usually see in electron window.Katharinekatharsis
But would still be nice for a proper answer on how to do thisKatharinekatharsis
because If you look at the package there are some known issues with angularKatharinekatharsis
@MatthiasSommer mmm just can't get it to work. getting an error. so if I look in my bin folder then I see the web pack but not in my package json. also I do get the following upon installing web pack -> ibb.co/kwrBiR . this is my code setup -> ibb.co/cFp8V6 .. the minute I type nom start I get the errorCleisthenes
The error message from the pictures says that you run the npm commands from the wrong directory. You have to run it from where package.json is located.Bicarbonate
@MatthiasSommer, mm no I am in the correct directoryCleisthenes
J
1

I personally hate pretty much all other answers out there on the internet. I chose to do something more off the wall. I do ALL development with just raw angular, and stub out the parts of the application that require electron things, like sharing the desktop, or getting a config file from somewhere like this:

if (!this.electron.isElectronApp) {
  return {
    config:data,
    more:data,
  }
} else {
  do electron things
}

It so far has worked wonderfully. If can anyone think how this is going to bite me in the butt later please share.

Janice answered 24/10, 2018 at 19:51 Comment(0)
G
1

First of all, we need to understand what actually is the issue being asked. There are two issues, as given below, regarding using electron with angular and live reload:

  1. How to reload Electron on the Build change
  2. How to reload Electron on the Source change

Now, when I was searching for the answer I actually was looking for issue no 2 but was getting the answer for issue no 1. There was so much confusion for me and no clear answer. So, let's get rid of this confusion and I am going to answer issue 2.

How to Reload Electron on the Source Change

This is clear that when we are developing the Angular app, we run the ng serve command, and the TS compiled to JS and put in memory and served from the memory instead of the disk (when we create the build).

So to use that in-memory source for live electron reload do the following:

Install the electron-reloader:

npm install electron-reloader --save-dev

Add this in the main.js file:

require('electron-reload')(__dirname, {
  electron: path.join(__dirname, 'node_modules/.bin/electron')
});

Run the Angular app in one terminal using ng serve and you will get the address something like this http://localhost:4200.

And in other terminal run electron, for this add "electron": "electron ." in your package.json scripts file and run node electrone.

Now in the main.js provide the local address in mainWindow.loadURL() as string.

Now, your electron app will get reloaded whenever you make changes and this will provide you with the same reload experience when the Angular app is run on the browser.

Gothar answered 21/4, 2021 at 21:35 Comment(0)
A
0

You can concurrently run ng build with watch and the electron.

"electron": "tsc application/start.ts && concurrently \"ng build --watch  --base-href ./\"  \"devMode=1 electron .\""

Also use electron-reload and configure it to reload every time the dist folder is changed.

require('electron-reload')(__dirname);

For the first time electron window will open with errors as dist folder is not generated, once the ng build is completed, dist will be generated and electron-reload will reload the app. After that on every change dist folder will change because of --watch and electron-reload will reload the app.

Related npm packages

https://www.npmjs.com/package/concurrently

https://www.npmjs.com/package/electron-reload

Altercation answered 29/7, 2020 at 10:18 Comment(0)
R
0

I use following solution (which parts came from internet) - for electron: ^19.0.4 with angular: 13 (on Windows 11):

Code compilation after changes

First in package.json we use ng build --watch code to detect changes and compile code (I will past my whole scripts - probably you can simplify it)

"runElectron": "electron .",
"ngBuildDevHmr": "ng build --watch --configuration dev  --optimization=false --build-optimizer=false",
"hmr": "node electron/edit-package.js --dev && copy config\\env-dev.json electron\\env.json && cd electron && tsc --skipLibCheck && cd .. && npm run ngBuildDevHmr"

I run it simply by npm run hrm in separate terminal to see compiler messages.

Electron update

Ok, now we chave fresh compiled code after changes - but electron don't know it yet. So it must detect than new code appears - we use for this following lib:

npm install --save-dev electron-reload

(do not confuse electron-reload (^2.0.0-alpha.1) with electron-reloader - that separate projects)

In main electron file angular\electron\main.ts I add this code to detect files changes (at the top directly below imports section)

if (!env.production) { 
    require('electron-reload')(
        __dirname+'\\..', // directory for detect changes
        {
            electron: path.join(__dirname+'\\..\\..', 'node_modules', '.bin', 'electron'), // path to electron executable
            hardResetMethod: 'exit' // hard reset after changes detection - you can comment it for better performance
        }
    );
}

Probably the directory in electron which conatins angular code is deleted and created - so we must detect changes in parent dir (__dirname+'\\..' above) and also we must reload whole page (which will be done in below code) because electron will loose access to previosly open (but currently deleted) folder. I detect it using did-fail-load event.

In middle part of main.ts where I get win = new BrowserWindow(... I add code which reload browser :

    if (!env.production) {
        win.webContents.on("did-fail-load", function() {
            win.loadURL(`file:///${__dirname}/../sqar-spaceplan-frontend/index.html`);
        });
    }

Finally in separate terminal I run npm run rumElectron

Rostrum answered 26/10, 2022 at 16:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.