Da ich mitlweile recht angetan von Angular bin, aber hin und wieder doch auf Dateiebene arbeiten muss, würde ich Angular gerne zusammen mit Electron ans laufen bringen.
Hierfür muss ich natürlich erst einmal ein Angular-Projekt erstellen. Hierfür nutze ich das Angular CLI
ng new testapp
Achschließend wird per npm noch electron installiert, und bei den dev-paketen registriert.
npm install electron@latest --save-dev
Nun haben wir eigentlich alles vorhanden, nur müssen noch ein paar Kleinigkeiten angepasst werden, dass electron auch wirklich läuft.
Als wird die app/index.html
angepasst. Hier muss auf des head.base_href attribut um ein Punkt ergänzt werden, da electron auf Datei-Basis arbeitet. Also <base href="./">
Anschließend erstelle ich noch im Root-Verzeichnis die Datei app.js
mit folgendem Inhalt
const { app, BrowserWindow } = require('electron') const url = require("url"); const path = require("path"); let appWindow function initWindow() { appWindow = new BrowserWindow({ width: 1000, height: 800, webPreferences: { nodeIntegration: true } }) // Electron Build Path appWindow.loadURL( url.format({ pathname: path.join(__dirname, `/dist/index.html`), protocol: "file:", slashes: true }) ); // Initialize the DevTools. appWindow.webContents.openDevTools() appWindow.on('closed', function () { appWindow = null }) } app.on('ready', initWindow) // Close when all windows are closed. app.on('window-all-closed', function () { // On macOS specific close process if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', function () { if (win === null) { initWindow() } })
Jetzt muss noch der Ausgabe-Pfad für das Kompilierte Angular-Projekt angepasst werden. Dies wird in der Datei angular.json
unter projects>PROJECT_NAME>architect>build>options>outputPath
erledigt. Hier entferne ich einfach den Projektnamen, sodass alles direkt in dem Ordner dist
landet.
Final muss dann noch die package.json
angepasst werden.
Als erstes wird die Electron-Main Datei definieren. registriert, dies wird erledigt, indem das Objekt um den Eintrag "main": "app.js"
erweitert wird.
Anschließend ergänzen wir noch die Scripte, sodass wir direkt die App erstellen und auch starten können.
{ "name": "AAAA", "version": "0.0.0", "main": "app.js", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", "build-electron": "ng build --base-href ./", "electron": "npm run build-electron && ./node_modules/.bin/electron ." }, ..... }
Und nun können wir Electron mit npm run electron
starten.
Ausliefern als Bundle
Da ich es aber gerne als Bundle ausliefern möchte sind noch ein paar kleine Schritte notwendig.
Als erstes installieren wir den Electron-Builder. Da die Doku gerne YARN hätte, bekommt sie yarn
yarn add electron-builder --dev
Nun müssen wir noch unsere Standard package.json
etwas erweitern.
{ "name": "PROJECTNAME", "version": "0.0.0", "main": "app.js", "author": "kcinnaySte", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", "build-electron": "ng build --base-href ./", "electron": "npm run build-electron && ./node_modules/.bin/electron .", "pack": "electron-builder --dir", "dist": "ng build --prod --base-href ./ && electron-builder -m -w -l" }, "build": { "appId": "example.app.id", "directories": { "output": "bundle" }, "mac": { "category" : "enter.mac.category" } }, ...... }
Hinzugekommen ist in diesem Fall der author
, sowie scripts.pack
und scripts.dist
Außerdem das ganze build
objekt neu, welches die entsprechenden Settings für den electron-builder beinhaltet. Die einzelnen Einträge sind recht selbsterklärend. Durch output
ist definiert, dass die gepackten Pakete im Verzeichnis bundle
landen. Standard wäre hier das Verzichnis dist
, aber das können wir ja nicht nehmen, da da ja bereits die Daten vom Angular landen.
Die mac.category
muss natürlich entsprechend der Apple-Vorgaben angepasst werden.
Nun wird unsere App durch ein Aufruf von npm run dist
zusammen gestellt, und landet in dem Ordner bundle
Zum Abschluss empfiehlt es sich nun noch, die .gitignore
um den Eintrag /bundle
zu ergänzen, da wir die Bundles ja nicht einchecken wollen.