Electron Js + jQuery + Bootstrap - Dev to Build
Join the DZone community and get the full member experience.
Join For FreeWhenever we need software, we go to a website and download a package, and after a couple of clicks, the software will be installed on your PC. As a web developer, you may not have experience in building a Desktop application.
In this article, we look into "how can we build a Desktop application with web technologies". If you Google the above-quoted text, the result will be Electron JS.
What Is Electron.js?
Electron's docs says, "Electron JS is a runtime framework that allows the user to create desktop-suite applications with HTML5, CSS, and JavaScript".
Here, you might be asking what is compiling our JS code we write. It combines the Chromium rendering engine and the Node. js runtime. So, to build an Electron application, we need basic knowledge of Node.js as a prerequisite. And I assume here that you are familiar with JS. I think, this fair enough for the introduction. Let's move on to the topic.
Prerequisites
* NodeJs & NPM : latest
* A code editor
Electron Forge helps us to create the electron app in an easy way. To understand the basics, let's go in the traditional way.
Create a folder wherever you want in your pc. Open cmd, and run npm init
. Please enter the details of the project for the generated package.json. Now, all we need is Electron JS. Electron JS is a dev dependency, and it should be installed globally. Install it with the help of npm install -g electron --only=dev
. Once installed, the package.json should have Electron as a devDependency. (If not please add it manually.)
xxxxxxxxxx
"devDependencies": {
"electron": "^10.1.3"
}
In Electron JS, there are two processes. One is the main process and the other is the renderer process. Let's check what docs say about Main and Renderer processes.
Main Process
In Electron, the process that runs package.json
's main
script is called the main process. The script that runs in the main process can display a GUI by creating web pages. An Electron app always has one main process, but never more.
Renderer Process
Since Electron uses Chromium for displaying web pages, Chromium's multi-process architecture is also used. Each web page in Electron runs in its own process, which is called the renderer process.
To communicate between the main and renderer processes, Electron provides us the support called Inter-Process Communication.
ipcMain: It listens to the events from the renderer processes.
xxxxxxxxxx
// In main process.
const { ipcMain } = require('electron')
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.returnValue = 'pong'
})
ipcRenderer: Communicates asynchronously from a renderer process to the main process.
xxxxxxxxxx
// In renderer process (web page).
const { ipcRenderer } = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"
I believe this is the right time to get our hands dirty. Create a main.js file in the project directory, and it should be mentioned in package.json's main
property. If it's not added in the process of npm init
, please add it manually.
xxxxxxxxxx
const { app, BrowserWindow, ipcMain} = require('electron')
const url = require('url')
const path = require('path')
function createWindow () {
// Create the browser window.
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
win.loadURL(url.format ({
pathname: path.join(__dirname, 'src/index.html'),
protocol: 'file:',
slashes: true
}))
// Open the DevTools.
win.webContents.openDevTools()
}
// Once our app is ready, we create an window and load index.html
app.whenReady().then(createWindow)
// on mac, processes will be running until user close it with cmd + q
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
// When app is active, At least one window should be open.
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
If you notice the win.loadURL()
, we load index.js, which lies in the src folder. Let's create an src folder inside our app dir. Here, we create index.html, index.js, and index.scss
.
Before we create them, let's take a step back and look at what we need.
We need to create a UI with a form that gets the date from the User and submits. So, We need jQuery, bootstrap, and a data-picker (js-datepicker).
npm install --save bootstrap
npm install --save jquery
npm install --save js-datepicker
Create index.js, and require all the packages you need.
xxxxxxxxxx
let $ = jQuery = require('jquery');
const datepicker = require('js-datepicker')
let date = datepicker("#mydate",{
formatter: (input, date, instance) => {
input.value = getFormattedDate(date)
}
})
$("form").submit(e=>{
e.preventDefault();
let date = $("#mydate").val();
console.log("picked date", date)
})
function getFormattedDate(date) {
return ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1)))
+ '-' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate()))
+ '-' + date.getFullYear()
}
Now, create an index.html and load index.js into it.
xxxxxxxxxx
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<!-- <link rel="stylesheet" href="./bootstrap.min.css"> -->
<!--If import scss is not working please try adding bootsrap manually from node modules-->
<link rel="stylesheet" href="./index.scss">
<link rel="stylesheet" href="../node_modules/js-datepicker/dist/datepicker.min.css">
<title>Dowload File</title>
</head>
<body>
<div class="center">
<h2>Dowload File</h2>
<form>
<div class="form-group">
<label for="mydate">Date :</label>
<div style="position:relative">
<input type="text" id="mydate" class="form-control" data-date-format="dd/mm/yyyy" placeholder="Select a Date">
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</body>
</html>
index.scss
xxxxxxxxxx
@import "~bootstrap/scss/bootstrap";
body{
background-color: #eee;
margin: auto;
}
.center {
margin: auto;
margin-top: 25px;
width: 50%;
border-radius: 25px;
padding: 10px;
}
In order to send the selected date to the main process, we have to require ipcMain
and ipcRenderer
in main.js and index.js respectively.
xxxxxxxxxx
//// Modification in index.js /////
// require ipcRenderer in index.js
const {ipcRenderer} = require('electron')
// modify form submit listener
$("form").submit(e=>{
e.preventDefault();
let date = $("#mydate").val();
console.log("picked date", date)
ipcRenderer.send("object-date", date);
})
/// modifications in main.js ///
// ipcMain is already required in main.js
// listener to pick the date
ipcMain.on("object-date",(e, date)=>{
console.log("selected date", date);
})
To run the app, we need to add script configuration in our package.json. Please add this in your package json.
xxxxxxxxxx
"scripts": {
"start": "electron ."
}
That's all. It's time to run our application. Open your cmd and cd to project dir. Then, run npm run start
. Now, we have our standalone app running.
How to Build as an .exe File
In order to build the app we created, we need to add another dev dependency called electron builder and script configurations. Run npm install electron-builder --only=dev
and change your package.json's script:
xxxxxxxxxx
{
.
"main": "main.js",
"scripts": {
"start": "electron .",
"dist": "electron-builder"
},
.
// now your dependencies will look like this.
"dependencies": {
"dotenv": "^8.2.0",
"jquery": "^3.5.1",
"js-datepicker": "^5.16.0"
},
"devDependencies": {
"electron": "^10.1.3",
"electron-builder": "^22.8.1"
}
}
Also, we need to write the build configuration in package.json:
{
..
"build": {
"appId": "app-name",
"win": {
"target": [
"nsis"
],
"icon": "src/icon/win.ico",
"requestedExecutionLevel": "requireAdministrator"
},
"nsis": {
"installerIcon": "src/icon/win.ico",
"uninstallerIcon": "src/icon/win.ico",
"uninstallDisplayName": "downloadClient",
"license": "license.txt",
"oneClick": false,
"allowToChangeInstallationDirectory": true
}
..
}
I have kept the icon in scr/icon/
. To check the build configurations of other OSs, please check the docs here.
Now, run npm run dist
. In a couple of minutes, you should be having your software ready in the dist folder.
That's all. We have the software ready to install. Happy coding. For complete code implementation, please visit my git repo.
Opinions expressed by DZone contributors are their own.
Comments