Project Description:
I have a functional front-end angularjs application that communicates with another back-end Java application deployed in tomcat running on different port(8443). I have been running it on a web browser but now i want to run it as a desktop application. I have been running it as grunt serve for development environment and grunt --clean --prod for production and distribution.
When run in dev mode using grunt serve, the application runs on http://localhost:9000/?baseApiUrl=https://localhost:8443&tenantIdentifier=demo
Question:
How do i go about making the application run in electron for dev mode and later package it for production? I tried How to port an existing angular app to electron? but it can't communication with the backed application on the port.
Please help.
Here's how,
1. The boilerplate code.
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow = null;
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600});
mainWindow.loadURL(`file://${__dirname}/index.html`);
//Take note of this line.
//mainWindow.loadURL(`http://localhost:9000`);
mainWindow.on('closed', function () {
mainWindow = null;
});
}
app.on('ready', createWindow);
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit();
}
})
app.on('activate', function () {
if (mainWindow === null) {
createWindow();
}
});
2. Take note of the line mainWindow.loadURL('file://${__dirname}/index.html'). Since your use case is to communicate with another backend application running on a port, using the file protocol (file://<uri>) won't work, you need to communicate with the port on http protocol.
3. To achieve this, I suggest to run a static files http server in your electron application, server your app over local server, and replace this mainWindow.loadURL('file://${__dirname}/index.html') line with mainWindow.loadURL(`http://localhost:9000`) this.
Edit 1:
You can run a very basic static files server like so, however there certainly are better ways to write it.
var express = require('express');
var server = express();
server.use('/', express.static(__dirname + '/'));
server.listen(9000);
Edit 2:
After some discussion in the comments, I decided to clone the repo and add the electron part myself, here's how I did it.
1. Install the following dependencies by running,
npm install --save electron express
2. index.js file
const electron = require('electron');
const path = require('path');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow = null;
var express = require('express');
var server = express();
let dir = path.join(__dirname, './dist/community-app');
server.use('/', express.static(dir));
server.listen(9000);
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600
});
mainWindow.loadURL(`http://localhost:9000`);
mainWindow.on('closed', function () {
mainWindow = null;
});
}
app.on('ready', createWindow);
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit();
}
})
app.on('activate', function () {
if (mainWindow === null) {
createWindow();
}
});
3. Add the following script in your package.json
"scripts": {
//...
"start": "electron ."
},
4. Result
PS: I had some troubles building angularjs project, because there were no build scripts in the project for windows, hence some styles are missing from the page.
Git repo:
https://github.com/openMF/community-app
Related
I am using ElectronJS in order to build a Desktop Application.
However, I would like to auto-update the changes in the code and see the result immediately.
For example, if I am creating a WebServer with express on localhost, alyways when i update the browser, i get the changes.
On the Go Live extension on VSCode, this happens automatically after CRTL + Save
Does there exist any similar functionality for electron?
My current alternative is to close the whole electron application and start it with npm start again...
Thanks.
use electron-hot-reload package get hotreload
import { mainReloader, rendererReloader } from 'electron-hot-reload';
import { app } from 'electron';
import path from 'path';
const mainFile = path.join(app.getAppPath(), 'dist', 'main.js');
const rendererFile = path.join(app.getAppPath(), 'dist', 'renderer.js');
mainReloader(mainFile, undefined, (error, path) => {
console.log("It is a main's process hook!");
});
rendererReloader(rendererFile, undefined, (error, path) => {
console.log("It is a renderer's process hook!");
});
Example project with configuration
https://github.com/valentineus/electron-hot-reload/tree/6feca4b65b78c674aea096906ecd7b46abebc36a/example/application/src
Found it on my own.
As #ShioT mentioned, this is called hot reload / live reload.
electron-reload | npm package
https://www.npmjs.com/package/electron-reload
Frontend
require('electron-reload')(__dirname);
Backend (hard reset)
const path = require('path')
require('electron-reload')(__dirname, {
// note that this path can vary
electron: path.join(__dirname, 'node_modules', '.bin', 'electron')
});
The simplest way I've found is using electron-reloader, after installation, just paste the following code at the top of the app entry file, and you're all set:
const { app } = require('electron')
app.isPackaged || require('electron-reloader')(module)
Is there any way to deploy a VueJS app locally without having it limited by the browser?
I want the user to be able to call the application from the command line, for example app_name --port 6000, and then be able to load up the app from http://127.0.0.1:6000 or any other port they selected. The important thing is, the Vue App must be able to import and use native NodeJS modules, such as fs and zeromq.
Vuejs code must run in a browser environment in which you don't have access to your hardware. So basically you have three options to achieve this:
1. Use Electron
Electron gives you a chromium instance in which your UI (Vuejs) code can run and a separate process in which you can have access to your hardware using nodejs.
2. Create a simple http server with node
In this case you need to create a server with nodejs. For example you can create a file named server.js like this:
const http = require('http');
const fs = require('fs')
http.createServer((req, res) => {
// Do something with fs
const data = fs.readFileSync('path/to/some/file');
// return back the data with http
http.writeHead(200, {ContentType: 'text/plain'})
http.write(data);
}).listen(8000)
And fetch the data in your Vuejs app with http like this:
export default {
data () {
return {
myData: null
}
},
methods: {
onSomeAction () {
const {data} = await axios.get('localhost:8000')
this.myData = data;
}
}
}
Now in your package.json you can put this to run both when npm serve is called:
...
"scripts": {
...
"serve": "node server.js & vue-cli-service serve"
}
3. Use Nuxt
In case you need to do something with your hardware ONCE, and BEFORE the render you can use Nuxt to access the hardware before rendering the Vuejs app and handing it over to your browser.
I am using app.setAsDefaultProtocolClient("bithop"); but when I navigate to bithop:// in my browser, I just get the default electron app. (Where it says "To run a local app...")
This is not packaged as a .asar app. The documentation on this seems to be very unclear.
app.setAsDefaultProtocolClient("bithop");
(This is the last line of app.js)
When I go to bithop:// from a web browser, it should open my electron app.
This is the entire script:
const {app, BrowserWindow} = require('electron');
let window;
function createWindow() {
window = new BrowserWindow({
width: 800,
height: 600,
frame: false
});
window.loadFile('pages/index.html');
//window.openDevTools();
window.on('closed', function () {
window = null;
});
};
app.on('ready', createWindow)
app.on('window-all-closed', app.quit)
//Register Protocol
app.setAsDefaultProtocolClient("bithop");
I found that I needed to download the electron binaries, and put my app inside it, instead of installing as an npm module. I used https://github.com/electron-userland/electron-packager, which was really simple.
I am just trying out electron and have a very simple app that should load a webpage when running npm start
var app = require('app');
var BrowserWindow = require('browser-window');
app.on('ready', function() {
var window = new BrowserWindow({
height : 750,
width: 1000,
frame: false
});
window.loadUrl('https://google.com');
});
But I get the error : TypeError: core.require is not a function
The commands I run are:
npm install electron-prebuilt
npm install app
npm install browser-window
My package.json is:
{
"name": "SimpleWeb",
"version" : "0.0.2",
"main" : "main.js",
"scripts" : {
"start" : "electron ."
}
}
I am not sure why I am getting the crash - could someone help me out here :-)
UPDATE WAS USING OLD CODE :-(
Replace the top 2 lines, with these 3.
var electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
Electron now contains all of it's 'parts' within the root Electron package. As such, you don't need the browser-window or app packages (I am not even sure what they are/do).
You can import the relevant parts straight out of the core electron package.
// One Line
var { app, BrowserWindow } = require('electron')
// OR
// Three Lines
var electron = require('electron')
var app = electron.app
var BrowserWindow = electron.BrowserWindow
Both approaches are valid. From there, everything else should be fine. 😊
So, im migrating my Angular2 WebApp into electron, I so far so good, i made the electron run the app with the electron command, but when I build the app there are some modules missing, like systemjs, and zonejs.
how can I include all node_modules on the build??
this is my index.js file (the electron config)
const {app, BrowserWindow} = require('electron')
const path = require('path')
const url = require('url')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 1200, height: 800, "node-integration": false})
// and load the index.html of the app.
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: false
}))
// Open the DevTools.
win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})
}
// 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.
app.on('ready', 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 (win === null) {
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.