Skip to content

Instantly share code, notes, and snippets.

@PavithMadusara
Created April 6, 2021 16:43
Show Gist options
  • Save PavithMadusara/73eee59b0ce743cc7696b80f597de5fe to your computer and use it in GitHub Desktop.
Save PavithMadusara/73eee59b0ce743cc7696b80f597de5fe to your computer and use it in GitHub Desktop.
ElectronJS with Angular and Serialport

Electron with Angular and Serialport

Install Angular CLI

npm i -g @angular/cli

Create Angular Application

ng new APP-NAME --routing

Install Dependencies

npm i -D @angular-builders/custom-webpack @angular-devkit/architect @angular-devkit/core commonjs copy-webpack-plugin electron electron-builder electron-reload fs hammerjs npm-run-all wait-on electron-rebuild
  • Serial Port
npm i serialport
  • For IPC Communication (Optional)
npm i ngx-electron

Update package.json

  "main":"main.js",
  "scripts": {
    "build": "npm run postinstall:electron && npm run electron:tsc && ng build",
    "build:dev": "npm run build -- -c dev",
    "build:prod": "npm run build -- -c production",
    "electron:tsc": "tsc main.ts",
    "electron:serve": "wait-on http-get://localhost:4200/ && npm run electron:tsc && electron ./ --serve",
    "electron:local": "npm run build:prod && electron .",
    "electron:linux": "npm run build:prod && npx electron-builder build --linux",
    "electron:windows": "npm run build:prod && npx electron-builder build --windows",
    "electron:mac": "npm run build:prod && npx electron-builder build --mac",
    "start": "npm run postinstall:electron && npm-run-all -p ng:serve electron:serve",
    "ng:serve": "ng serve",
    "ng:serve:web": "npm run postinstall:web && npm run electron:tsc  && ng serve -o",
    "postinstall": "npm run postinstall:electron && npx electron-builder install-app-deps",
    "postinstall:web": "node postinstall-web",
    "postinstall:electron": "node postinstall",
    "install": "electron-rebuild"
  },

Create ~/main.ts File (make sure to change app name : line 46 ish)

import {app, BrowserWindow} from 'electron';
import * as url from 'url';
import * as path from 'path';

let mainWindow: BrowserWindow = null;

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

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true,
    },
  });
  mainWindow.maximize();

  if (serve) {
    require('electron-reload')(__dirname, {
      electron: require(`${__dirname}/node_modules/electron`),
    });
    mainWindow.loadURL('http://localhost:4200');
    mainWindow.show();
    mainWindow.webContents.openDevTools();
  } else {
    mainWindow.loadURL(
      url.format({
        pathname: path.join(__dirname, `/dist/APP-NAME/index.html`),
        protocol: 'file',
        slashes: true,
      }),
    );
  }

  mainWindow.on('closed', () => {
    mainWindow = null;
  });

}

try {

  app.on('ready', createWindow);

  app.on('activate', () => {
    if (mainWindow === null) {
      console.log('main window null');
      createWindow();
    }
  });
} catch (e) {
  console.log(e);
}

Add ~/electron-builder.json

{
    "productName": "App Name",
    "directories": {
      "output": "out"
    },
  "files": [
      "**/*",
      "!*.ts",
      "!*.code-workspace",
      "!LICENSE.md",
      "!package.json",
      "!package-lock.json",
      "!src/",
      "!e2e/",
      "!hooks/",
      "!.angular-cli.json",
      "!_config.yml",
      "!karma.conf.js",
      "!tsconfig.app.json",
      "!tsconfig.json",
      "!tsconfig.spec.json",
      "!tslint.json"
    ],
    "win": {
      "icon": "dist/assets/icons",
      "target": [
        "portable"
      ]
    },
    "mac": {
      "icon": "dist",
      "target": [
        "dmg"
      ]
    },
    "linux": {
      "icon": "dist",
      "target": [
        "AppImage"
      ]
    }
  }

Add Post Install Configs

  • postinstall.js
const fs = require('fs');
const f_angular = 'node_modules/@angular-devkit/build-angular/src/webpack/configs/browser.js';
const {getConfigs} = require('./postinstall.config');

const {electronConfig} = getConfigs();
fs.readFile(f_angular, 'utf8', function (err, data) {

  if (err) {
    return console.log(err);
  }

  let result = data.replace(/return {[\s\S]+?$/m, 'return {');
  result = result.replace(/target: "web", /g, '');
  result = result.replace(/return \{/g, 'return {' + electronConfig);

  fs.writeFile(f_angular, result, 'utf8', function (err) {
    if (err) return console.log(err);
  });
});
  • postinstall-web.js
const fs = require('fs');
const f_angular = 'node_modules/@angular-devkit/build-angular/src/webpack/configs/browser.js';
const {getConfigs} = require('./postinstall.config');

const {webConfig} = getConfigs();
fs.readFile(f_angular, 'utf8', function (err, data) {

  if (err) {
    return console.log(err);
  }

  let result = data.replace(/return {[\s\S]+?$/m, 'return {');
  result = result.replace(/target: "web",/g, '');
  result = result.replace(/return \{/g, 'return {' + webConfig);

  fs.writeFile(f_angular, result, 'utf8', function (err) {
    if (err) return console.log(err);
  });
});
  • postinstall.config.js
const config = require('./extra-webpack.config.js');

module.exports.getConfigs = function () {
  config.target = 'electron-renderer';
  electronConfig = JSON.stringify(config).slice(1, -1) + ',';

  config.target = 'web';
  webConfig = JSON.stringify(config).slice(1, -1) + ',';

  return {
    electronConfig,
    webConfig
  };
};

Add Webpack Configs

  • extra-webpack.config.js
const path = require('path');

module.exports = {
  target: 'electron-renderer',
  externals: {
  },
  resolve: {
    alias: {
      typeorm: path.resolve(__dirname, "../node_modules/typeorm/typeorm-model-shim")
    }
  }
};

Fixing Common Errors and Dependency Version Conflicts

  • Namespace someting has no exported member someting
Update @type/node to latest version
  • prebuilt-install 404 for serialport bindings
This happens when serialport doesn't have prebuilt binaries for your specific chromium version
Check electron Doc or Blog to find the corresponding chromium version and make sure that serialport
has a prebuilt binary for that version. otherwise, you need to upgrade/downgrade your electron version 
You can also try adding  "buildDependenciesFromSource": true, to electron-builder.json

Run npm install

Then npm run start

Fixing more Errors

  • Zone.js is required
Add import 'zone.js'; to ~/src/main.ts
  • Cannot load resources polyfills,styles etc
Update ~/src/index.html base tag to <base href="">

this gist finished with exit code 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment