Bouw een desktop-applicatie met Electron en Angular

In deze zelfstudie bouwen we een platformonafhankelijke desktoptoepassing met Electron en webtechnologieën zoals TypeScript en Angular.

Electron.js is een populair platform voor het bouwen van platformonafhankelijke desktop-apps voor Windows, Linux en macOS met JavaScript, HTML en CSS. Het is gemaakt en onderhouden door GitHub en is beschikbaar onder de MIT-permissieve licentie. Het is oorspronkelijk gemaakt voor GitHub's Atom-editor, maar is sindsdien gebruikt om applicaties te maken door bedrijven als Microsoft (Visual Studio Code), Facebook, Slack en Docker.

Electron maakt gebruik van krachtige platforms zoals Google Chromium en Node.js, maar biedt ook zijn eigen set rijke API's voor interactie met het onderliggende besturingssysteem.

Electron biedt een native container die web-apps omhult, zodat ze eruitzien en aanvoelen als desktop-apps met toegang tot functies van het besturingssysteem (vergelijkbaar met Cordova voor mobiele apps). Dit betekent dat we elke JavaScript-bibliotheek of -framework kunnen gebruiken om onze applicatie te bouwen. In deze zelfstudie gebruiken we Angular.

Vereisten

Voor deze zelfstudie moet u aan de volgende vereisten voldoen:

  • Bekendheid met TypeScript en Angular.
  • Node.js en npm geïnstalleerd op uw ontwikkelmachine.

Hoekige CLI installeren

Laten we beginnen met het installeren van Angular CLI, de officiële tool voor het maken van en werken met Angular-projecten. Open een nieuwe terminal en voer het volgende commando uit:

npm install -g @angular/cli

We installeren de Angular CLI wereldwijd op ons systeem. Als de opdracht mislukt met de EACCESS fout, voeg sudo toe vóór uw opdracht in Linux of macOS, of voer de opdrachtprompt uit als beheerder in Windows.

Als de CLI met succes is geïnstalleerd, navigeert u naar uw werkmap en maakt u een nieuw Angular-project met de volgende opdrachten:

cd ~
ng new electron-angular-demo

Wacht tot de bestanden van uw project zijn gegenereerd en afhankelijkheden zijn geïnstalleerd vanaf npm. Navigeer vervolgens naar de hoofdmap van uw project en voer de volgende opdracht uit om de nieuwste versie van Electron van npm te installeren als ontwikkelingsafhankelijkheid:

npm install --save-dev electron@latest

Op het moment van schrijven zal dit commando Electron v4.1.4 . installeren .

Maak vervolgens een main.js bestand en voeg de volgende code toe:

    const {app, BrowserWindow} = require('electron')
    const url = require("url");
    const path = require("path");

    let mainWindow

    function createWindow () {
      mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: true
        }
      })

      mainWindow.loadURL(
        url.format({
          pathname: path.join(__dirname, `/dist/index.html`),
          protocol: "file:",
          slashes: true
        })
      );
      // Open the DevTools.
      mainWindow.webContents.openDevTools()

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

Deze code maakt eenvoudig een GUI-venster en laadt de index.html bestand dat beschikbaar zou moeten zijn onder de dist map nadat we onze Angular-toepassing hebben gebouwd. Deze voorbeeldcode is overgenomen van de officiële startersrepository.

Open vervolgens de package.json bestand van uw project en voeg de main toets om de main.js . in te stellen bestand als het belangrijkste toegangspunt:

    {
      "name": "electron-angular-demo",
      "version": "0.0.0",
      "main": "main.js",
      // [...]
    }

Vervolgens moeten we een script toevoegen om de Electron-app gemakkelijk te starten na het bouwen van het Angular-project:

    {
      "name": "electron-angular-demo",
      "version": "0.0.0",
      "main": "main.js",
      "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e",
        "start:electron": "ng build --base-href ./ && electron ."
      }, 
      // [...]
    }

We hebben de start:electron . toegevoegd script dat de ng build --base-href ./ && electron . . uitvoert commando:

  • De ng build --base-href ./ een deel van de opdracht bouwt de Angular-app en stelt de base href in op ./ .
  • De electron . een deel van de opdracht start onze Electron-app vanuit de huidige map.

Voer nu in uw terminal de volgende opdracht uit:

npm run start:electron

Een Electron GUI-venster wordt geopend, maar is leeg. In de console ziet u de Niet toegestaan ​​om lokale bron te laden:/electron-angular-demo/dist/index.html fout.

Electron kan het bestand niet laden van de dist map omdat deze gewoon niet bestaat. Als u in de map van uw project kijkt, ziet u dat Angular CLI uw app bouwt in de dist/electron-angular-demo map in plaats van alleen de dist map.

In onze main.js bestand, vertellen we Electron om te zoeken naar de index.html bestand in de dist map zonder een submap:

       mainWindow.loadURL(
        url.format({
          pathname: path.join(__dirname, `/dist/index.html`),
          protocol: "file:",
          slashes: true
        })
      );

__dirname verwijst naar de huidige map van waaruit we Electron gebruiken.

We gebruiken de path.join() methode om het pad van de huidige map samen te voegen met de /dist/index.html pad.

U kunt het tweede deel van het pad wijzigen in /dist/electron-angular-demo/index.html of, beter nog, verander de Angular-configuratie om de bestanden in de dist . uit te voeren map zonder een submap te gebruiken.

Open de angular.json bestand, zoek de projects → architect → build → options → outputPath sleutel en verander de waarde van dist/electron-angular-demo naar gewoon dist :

      "projects": {
        "electron-angular-demo": {
          "root": "",
          "sourceRoot": "src",
          "projectType": "application",
          "prefix": "app",
          "schematics": {},
          "architect": {
            "build": {
              "builder": "@angular-devkit/build-angular:browser",
              "options": {
                "outputPath": "dist", 

Ga terug naar je terminal en voer opnieuw de volgende opdracht uit:

npm run start:electron

Het script roept de ng build . aan commando om de Angular-app te bouwen in de dist map, en bel electron uit de huidige map om het Electron-venster te starten met de Angular-app geladen.

Dit is een screenshot van onze desktop-app met Angular:

Elektronen-API's aanroepen vanuit Angular

Laten we nu kijken hoe we Electron API's vanuit Angular kunnen aanroepen.

Electron-apps maken gebruik van een hoofdproces met Node.js en een rendererproces met de Chromium-browser. We hebben niet rechtstreeks toegang tot alle API's van Electron vanuit de Angular-app.

We moeten gebruik maken van IPC of Inter-Process Communication, een mechanisme dat door besturingssystemen wordt geboden om communicatie tussen verschillende processen mogelijk te maken.

Niet alle Electron API's hoeven vanuit het hoofdproces te worden geopend. Sommige API's zijn toegankelijk vanuit het rendererproces en sommige API's zijn toegankelijk vanuit zowel het hoofd- als het rendererproces.

BrowserWindow, dat wordt gebruikt om browservensters te maken en te besturen, is alleen beschikbaar in het hoofdproces. De desktopCapturer API (gebruikt voor het vastleggen van audio en video vanaf de desktop met behulp van de navigator.mediaDevices.getUserMedia API) is alleen beschikbaar in het rendererproces. Ondertussen is de klembord-API (voor het uitvoeren van kopieer- en plakbewerkingen op het systeemklembord) beschikbaar voor zowel het hoofd- als het rendererproces.

U kunt de volledige lijst met API's bekijken in de officiële documenten.

Laten we een voorbeeld bekijken van het aanroepen van de BrowserWindow API, alleen beschikbaar in het hoofdproces, vanuit de Angular-app.

Open de main.js bestand en importeer ipcMain :

    const {app, BrowserWindow, ipcMain} = require('electron')

Definieer vervolgens de openModal() functie:

    function openModal(){
      const { BrowserWindow } = require('electron');
      let modal = new BrowserWindow({ parent: mainWindow, modal: true, show: false })
      modal.loadURL('https://www.sitepoint.com')
      modal.once('ready-to-show', () => {
        modal.show()
      })
    }

Deze methode zal een kind modaal venster creëren, laad de https://www.sitepoint.com URL erin en geef het weer als het klaar is.

Luister vervolgens naar een openModal bericht dat wordt verzonden vanuit het rendererproces en roept de openModal() . op functie wanneer het bericht is ontvangen:

    ipcMain.on('openModal', (event, arg) => {
      openModal()
    })

Open nu de src/app/app.component.ts bestand en voeg de volgende import toe:

import { IpcRenderer } from 'electron';

Definieer vervolgens een ipc variabele en bel require('electron').ipcRenderer ipcRenderer importeren in uw hoekcomponent:

      private ipc: IpcRenderer
      constructor(){
        if ((<any>window).require) {
          try {
            this.ipc = (<any>window).require('electron').ipcRenderer;
          } catch (e) {
            throw e;
          }
        } else {
          console.warn('App not running inside Electron!');
        }
      }

De require() methode wordt tijdens runtime in het rendererproces geïnjecteerd door Electron en is als zodanig alleen beschikbaar wanneer uw webtoepassing in Electron wordt uitgevoerd.

Voeg ten slotte de volgende openModal() toe methode:

      openModal(){
        console.log("Open a modal");
        this.ipc.send("openModal");
      }

We gebruiken de send() methode van ipcRenderer om een ​​openModal . te sturen bericht aan het hoofdproces.

Open de src/app/app.component.html bestand en voeg een knop toe, bind deze vervolgens aan de openModal() methode:

    <button (click)="openModal()">
      Open Modal
    </button>

Voer nu uw desktop-app uit met de volgende opdracht:

npm run start:electron

Dit is een screenshot van het hoofdvenster met een knop:

Als u klikt op de Modal openen knop, moet een modaal venster worden geopend met de SitePoint-website:

Je kunt de broncode van deze demo vinden in deze GitHub-repository.

Conclusie

In deze zelfstudie hebben we gekeken naar het uitvoeren van een webtoepassing die is gebouwd met Angular als desktoptoepassing met Electron. We hopen dat je hebt geleerd hoe gemakkelijk het kan zijn om te beginnen met het bouwen van desktop-apps met je toolkit voor webontwikkeling!