Hot Reload in ElectronJS - GeeksforGeeks

22 Oct, 2021
ElectronJS is an Open Source Framework used for building Cross-Platform native desktop applications using web technologies such as HTML, CSS, and JavaScript which are capable of running on Windows, macOS, and Linux operating systems. It combines the Chromium engine and NodeJS into a Single Runtime.
Several powerful frameworks such as Angular, AngularJS 1.x, React, React-Native, etc implement a tool like Webpack. Webpack is a static module bundler for modern JavaScript applications. It is a powerful tool that provides utilities to make the development process faster and better. One of the most useful features provided by webpack is Hot Reloading Capability. Hot Reloading capability lets the developer modify project source code to instantly reflect changes in the output/browser without updating the entire state of the application. The electron does not provide any in-built hot reloading module however, we can still implement hot reloading capability using open-source packages. This tutorial will demonstrate how to implement hot reloading in Electron using electron-reload npm package and electron-reloader npm package.
We assume that you are familiar with the prerequisites as covered in the above-mentioned link. For Electron to work, node and npm need to be pre-installed in the system.
Project Structure:
Example: We will start by building the basic Electron Application by following the given steps.
Step 1: Navigate to an Empty Directory to setup the project, and run the following command,npm initTo generate the package.json file. Install Electron using npm if it is not installed.npm install electron --saveThis command will also create the package-lock.json file and install the required node_modules dependencies. Once Electron has been successfully installed, Open the package.json file and perform the necessary changes under the scripts key. Install electron-reload using npm and save it as a dev dependency.npm install electron-reload --save-devInstall electron-reloader using npm and save it as a dev dependency.npm install electron-reloader --save-devBoth of these respective packages can be used to implement Hot Reload in Electron.package.json:{
  "name": "electron-hot",
  "version": "1.0.0",
  "description": "Hot Reload for Electron",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.2.5"
  },
  "devDependencies": {
    "electron-reload": "^1.5.0",
    "electron-reloader": "^1.0.1"
  }
}

npm init
To generate the package.json file. Install Electron using npm if it is not installed.
npm install electron --save
This command will also create the package-lock.json file and install the required node_modules dependencies. Once Electron has been successfully installed, Open the package.json file and perform the necessary changes under the scripts key. Install electron-reload using npm and save it as a dev dependency.
npm install electron-reload --save-dev
Install electron-reloader using npm and save it as a dev dependency.
npm install electron-reloader --save-dev
Both of these respective packages can be used to implement Hot Reload in Electron.
package.json:
{
  "name": "electron-hot",
  "version": "1.0.0",
  "description": "Hot Reload for Electron",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.2.5"
  },
  "devDependencies": {
    "electron-reload": "^1.5.0",
    "electron-reloader": "^1.0.1"
  }
}

Step 2: Create a main.js file according to the project structure. This file is the Main Process and acts as an entry point into the application. Copy the Boilerplate code for the main.js file as given in the following link.main.js:const { app, BrowserWindow } = require('electron')  function createWindow() {    // Create the browser window.    const win = new BrowserWindow({        width: 800,        height: 600,        webPreferences: {            nodeIntegration: true        }    })      // Load the index.html of the app.    win.loadFile('index.html')      // Open the DevTools.    win.webContents.openDevTools()}  // This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.// This method is equivalent to 'app.on('ready', function())'app.whenReady().then(createWindow)  // Quit when all windows are closed.app.on('window-all-closed', () => {    // On macOS it is common for applications and their     // menu bar to stay active until the user quits     // explicitly with Cmd + Q    if (process.platform !== 'darwin') {        app.quit()    }})  app.on('activate', () => {    // On macOS it's common to re-create a window in the     // app when the dock icon is clicked and there are no     // other windows open.    if (BrowserWindow.getAllWindows().length === 0) {        createWindow()    }})  // In this file, you can include the rest of your // app's specific main process code. You can also // put them in separate files and require them here.
main.js:
const { app, BrowserWindow } = require('electron')  function createWindow() {    // Create the browser window.    const win = new BrowserWindow({        width: 800,        height: 600,        webPreferences: {            nodeIntegration: true        }    })      // Load the index.html of the app.    win.loadFile('index.html')      // Open the DevTools.    win.webContents.openDevTools()}  // This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.// This method is equivalent to 'app.on('ready', function())'app.whenReady().then(createWindow)  // Quit when all windows are closed.app.on('window-all-closed', () => {    // On macOS it is common for applications and their     // menu bar to stay active until the user quits     // explicitly with Cmd + Q    if (process.platform !== 'darwin') {        app.quit()    }})  app.on('activate', () => {    // On macOS it's common to re-create a window in the     // app when the dock icon is clicked and there are no     // other windows open.    if (BrowserWindow.getAllWindows().length === 0) {        createWindow()    }})  // In this file, you can include the rest of your // app's specific main process code. You can also // put them in separate files and require them here.
Step 3: Create the index.html file within the src directory. We will also copy the boilerplate code for the index.html file from the above-mentioned link.index.html:<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>Hello World!</title>    <!-- https://electronjs.org/docs/tutorial                           /security#csp-meta-tag -->    <meta http-equiv="Content-Security-Policy"           content="script-src 'self' 'unsafe-inline';" />  </head>  <body>    <h1>Hello World!</h1>    We are using node     <script>        document.write(process.versions.node)    </script>, Chrome     <script>        document.write(process.versions.chrome)    </script>, and Electron     <script>        document.write(process.versions.electron)    </script>.  </body></html>
<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>Hello World!</title>    <!-- https://electronjs.org/docs/tutorial                           /security#csp-meta-tag -->    <meta http-equiv="Content-Security-Policy"           content="script-src 'self' 'unsafe-inline';" />  </head>  <body>    <h1>Hello World!</h1>    We are using node     <script>        document.write(process.versions.node)    </script>, Chrome     <script>        document.write(process.versions.chrome)    </script>, and Electron     <script>        document.write(process.versions.electron)    </script>.  </body></html>
Output: To launch the Electron Application, run the Command:npm start
npm start
Hot Reload in Electron: Hot Reloading should only be implemented in the development environment. Therefore we need to have control over the application environment before implementing this feature. NodeJS provides us with a way by which we can control the application environment via code using Environment Variables.
main.js: Add the following snippet in that file.
const env = process.env.NODE_ENV || 'development';
The NODE_ENV is an Environment Variable which stands for node environment in NodeJS. When a Node application is launched, it can check this environment variable and based on the value perform additional tasks and code logic. According to convention there should be only two values defined for the NODE_ENV variable i.e. either production or development however we can define as many values as required. We can define additional value such as test to execute automated test cases within the application. If we have not set the environment variable and have not explicitly defined the value within code then it will default to undefined.
To set the NODE_ENV in Windows from Windows Powershell use:$env:NODE_ENV="production"
$env:NODE_ENV="production"
To set the NODE_ENV in Windows from CMD use:set NODE_ENV=production
set NODE_ENV=production
To set the NODE_ENV in Linux and macOS use:export NODE_ENV=production
export NODE_ENV=production
Note: The NODE_ENV variable will be reset on System Reboot if set using the above methods. To persist this value in the System, set it in the System Environment Variables via Control Panel in Windows. We can also set NODE_ENV on application startup from package.json by updating the start script.
package.json:/..
"start": "set NODE_ENV=development&&electron ."
../
/..
"start": "set NODE_ENV=development&&electron ."
../
In the code, we have set the NODE_ENV to development. We can implement Hot Reload in Electron by following any of the two approaches:
Approach 1: Using electron-reload npm package.This package is used to load the contents of all active BrowserWindow Instances within Electron when the source files are changed. The require(‘electron-reload’)(path, options) takes in the following parameters. For more detailed Information, Refer this link.path: String The desired file path to watch to let it refresh the BrowserWindow Instances on source code change.options: Object (Optional) It takes in the following parameterselectron: String To implement a hard reset (Starting a new Electron Process) on reload, we can specify the path pointing to electron executables.hardResetMethod: String If the electron application overrides the default quit or close behaviour such as not closing all BrowserWindow Instances, then electron-reload can leave multiple instances of the app running. In such cases we can specify this property to change the default behavior of electron-reload to exit instead of quit.main.js: Add the following snippet in that file.const path = require('path')const env = process.env.NODE_ENV || 'development';  // If development environmentif (env === 'development') {    require('electron-reload')(__dirname, {        electron: path.join(__dirname, 'node_modules', '.bin', 'electron'),        hardResetMethod: 'exit'    });}Output:
path: String The desired file path to watch to let it refresh the BrowserWindow Instances on source code change.
options: Object (Optional) It takes in the following parameterselectron: String To implement a hard reset (Starting a new Electron Process) on reload, we can specify the path pointing to electron executables.hardResetMethod: String If the electron application overrides the default quit or close behaviour such as not closing all BrowserWindow Instances, then electron-reload can leave multiple instances of the app running. In such cases we can specify this property to change the default behavior of electron-reload to exit instead of quit.
electron: String To implement a hard reset (Starting a new Electron Process) on reload, we can specify the path pointing to electron executables.
hardResetMethod: String If the electron application overrides the default quit or close behaviour such as not closing all BrowserWindow Instances, then electron-reload can leave multiple instances of the app running. In such cases we can specify this property to change the default behavior of electron-reload to exit instead of quit.
main.js: Add the following snippet in that file.
const path = require('path')const env = process.env.NODE_ENV || 'development';  // If development environmentif (env === 'development') {    require('electron-reload')(__dirname, {        electron: path.join(__dirname, 'node_modules', '.bin', 'electron'),        hardResetMethod: 'exit'    });}
Output:
Approach 2: Using electron-reloader npm package. This package requires Electron 5+.According to the default behaviour of electron-reloader package, when source code of the files used in the Main Process are changed then the app is restarted, and when the source code of files used in the BrowserWindow Instance or Renderer Process are changed then the page is reloaded. The require(‘electron-reloader’)(module, options) takes in the following parameters. This package also watches the dist folder which is created when we build the application. For more detailed Information, Refer this link.module: Object The global module Object. This object is passed so that the package can read the module graph and find out which files belong to the Main Process.options: Object (Optional) It takes in the following parametersdebug: Boolean Prints the watched paths and file information such as file name of the files being watched on source code change. Default value is false.ignore: String[] It is a String Array of Regex Expressions. The Regex Expressions represent the pattern of the files/directories to be ignored by the package. By default, files/directories starting with a ., .map files, and node_modules dependencies are ignored. Additional patterns specified will be added to these default patterns.watchRenderer: Boolean Watch files used in the Renderer Process and reload the respective window on source code change. Default value is true.Note: The try/catch is needed so that it does not throw the following Error in production Environment.Cannot find module 'electron-reloader'main.js: Add the following snippet in that file.const env = process.env.NODE_ENV || 'development';  // If development environmentif (env === 'development') {    try {        require('electron-reloader')(module, {            debug: true,            watchRenderer: true        });    } catch (_) { console.log('Error'); }    }Output:Console Output:
According to the default behaviour of electron-reloader package, when source code of the files used in the Main Process are changed then the app is restarted, and when the source code of files used in the BrowserWindow Instance or Renderer Process are changed then the page is reloaded. The require(‘electron-reloader’)(module, options) takes in the following parameters. This package also watches the dist folder which is created when we build the application. For more detailed Information, Refer this link.
module: Object The global module Object. This object is passed so that the package can read the module graph and find out which files belong to the Main Process.
options: Object (Optional) It takes in the following parametersdebug: Boolean Prints the watched paths and file information such as file name of the files being watched on source code change. Default value is false.ignore: String[] It is a String Array of Regex Expressions. The Regex Expressions represent the pattern of the files/directories to be ignored by the package. By default, files/directories starting with a ., .map files, and node_modules dependencies are ignored. Additional patterns specified will be added to these default patterns.watchRenderer: Boolean Watch files used in the Renderer Process and reload the respective window on source code change. Default value is true.
debug: Boolean Prints the watched paths and file information such as file name of the files being watched on source code change. Default value is false.
ignore: String[] It is a String Array of Regex Expressions. The Regex Expressions represent the pattern of the files/directories to be ignored by the package. By default, files/directories starting with a ., .map files, and node_modules dependencies are ignored. Additional patterns specified will be added to these default patterns.
watchRenderer: Boolean Watch files used in the Renderer Process and reload the respective window on source code change. Default value is true.
Note: The try/catch is needed so that it does not throw the following Error in production Environment.
Cannot find module 'electron-reloader'
main.js: Add the following snippet in that file.
const env = process.env.NODE_ENV || 'development';  // If development environmentif (env === 'development') {    try {        require('electron-reloader')(module, {            debug: true,            watchRenderer: true        });    } catch (_) { console.log('Error'); }    }
Output:
Console Output:
arorakashish0911
ElectronJS
JavaScript
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Difference between var, let and const keywords in JavaScript
Differences between Functional Components and Class Components in React
Convert a string to an integer in JavaScript
How to append HTML code to a div using JavaScript ?
Difference Between PUT and PATCH Request
Roadmap to Become a Web Developer in 2022
Installation of Node.js on Linux
Top 10 Projects For Beginners To Practice HTML and CSS Skills
How to fetch data from an API in ReactJS ?
How to insert spaces/tabs in text using HTML/CSS?