Sådan oprettes en Electron-app ved hjælp af Angular og SQLite3.

Jeg eksperimenterede for nylig med at konvertere en af ​​mine Angular webapps til en desktopapplikation ved hjælp af Electron. Jeg stødte på et par forhindringer undervejs og besluttede at skrive min erfaring skriftligt, så det kan hjælpe andre. Hvis du har lignende planer for dit projekt, håber jeg, at dette kan være nyttigt. Kildekoden til denne vejledning kan findes her.

Del I: Kantet

Opret kedelpladen.

Af hensyn til denne guide opretter vi en ny Angular-app fra bunden. Jeg bruger Electron-Forge til at skabe kedelpladen. Electron-Forge tilbyder flere skabeloner til oprettelse af kedelpladekode, herunder en til Angular 2. Installer først Electron-Forge CLI.

$ npm i -g electron-forge

Brug nu CLI til at oprette kogepladen Angular.

$ electron-forge init electron-angular-sqlite3 --template=angular2$ cd electron-angular-sqlite3

Forge CLI vil tilføje det helt nødvendige, som vi har brug for for at køre vores app. Lad os tilføje et par ekstra mapper for at huse vores databasefiler. Tilføj en aktivmappe under src, og læg data og modelmapper under den.

$ mkdir ./src/assets/data ./src/assets/model

Katalogtræet skal nu se sådan ud:

.+-node_modules+-src| || +-assets| | || | +-data| | +-model| || +-app.component.ts| +-bootstrap.ts| +-index.html| +-index.ts|+-.compilerc+-.gitignore+-package-lock.json+-package.json+-tsconfig.json+-tslint.json

Skriv noget kode.

Lad os som vores første trin tilføje en modelfil, som vi matcher vores databaseskema. Lad os i dette enkle eksempel oprette en klasse kaldet Item. Hvert element indeholder et id og et navnegenskab. Gem filen i dit projekt på src/assets/model/item.schema.ts.

Vi bruger TypeORM til vores objektrelationskortlægning. Første installation TypeORM.

$ npm install typeorm --save

Vi følger TypeORM-guiden til oprettelse af skema her. Når du er færdig, skal filen se sådan ud:

TypeORM benytter sig af skriveskrivere. Vi bruger Entity-dekoratøren til at erklære vores vareklasse som et bord. Den @PrimaryGeneratedColumn()dekoratør erklærer idsom vores unikke identifikation og fortæller databasen til automatisk at generere den. Vi vil bekymre os om at linke til en database senere.

Opret tjenesten.

Vores næste sandsynlige handling ville være at oprette en apptjeneste, der håndterer kommunikation fra front til bagende. Electron stiller IpcRendererklassen til rådighed for netop denne ting. IpcRendererer Electrons inter-proces kommunikationsklasse, der bruges i renderer-processen. Dybest set vil vi bruge til IpcRendererat sende meddelelser til Electrons hovedproces. Disse meddelelser videregiver oplysninger til hovedprocessen, så den kan håndtere databaseinteraktioner.

Implementering af det IpcRendererer, hvor vi støder på vores første forhindring. Electron stoler på metoden window.require (), som kun er tilgængelig inden for Electrons gengivelsesproces. Dette er et veldokumenteret problem. For at omgå dette kan vi bruge ThornstonHans 'ngx-elektron-pakke, der indpakker alle elektron-API'erne, der er udsat for rendererprocessen, i en enkelt elektrontjeneste. Du kan læse mere om dette her.

Inden vi kan bruge ngx-electron, skal vi installere det.

$ npm install ngx-electron --save

Lad os nu oprette en tjeneste til at håndtere vores IpcRendererkommunikation. Opret src/app.service.ts.

I app.service.tsopretter vi en klasse kaldet AppServiceog tilføjer @Injectable()dekoratøren. Dette giver os mulighed for at bruge vinkelens indbyggede afhængighedsinjektion (DI). I vores konstruktør opretter vi en lokal variabel _electronServiceaf typen ElectronService. Den ElectronServiceklasse leveres til os af ngrx-electron. Det giver os mulighed for at bruge Electrons IpcRenderklasse uden nogen af ​​de førnævnte problemer.

Vi opretter tre funktioner: en der får alle varer i databasen, en til at føje en vare til databasen og en til at slette en vare. Hver funktion returnerer en observerbar.

Observerbare er en del af RxJs-biblioteket og giver en god måde at håndtere vores databaseinteraktioner asynkront på. Du kan læse mere om Observables her. Bemærk brugen af ​​den observerbare operatør oftil at angive, at vi indpakker vores svar fra this._electronService.ipcRenderer.sendSync()som en observerbar værdi.

Registrering af tjenester og skrivekomponent.

Når vores service er færdig, lad os gå ind src/app.component.tsog registrere den til DI. Mens vi er derinde, tilføjer vi en simpel html-skabelon og funktioner til at håndtere vores knaphændelser.

Sørg for at tilføje AppServicesom udbyder i @NgModuledekoratørargumenterne og også som en privat variabel i AppComponentkonstruktøren. Vi skal også tilføje ElectronServicesom udbyder.

Ved initialisering af vores komponent ønsker vi at indlæse alt indhold i vores database og vise det. For at gøre dette abonnerer vi på addItem()funktionen af ​​den service, vi oprettede. Hvis du husker det, returnerer alle vores servicefunktioner Observables. For at få data fra vores observerbare abonnerer vi på det og sender en tilbagekaldsfunktion, der kører, når dataene modtages. I eksemplet ovenfor (items) => (this.itemList = iteudfylder ms) vores klassevariabler le itemLmed indholdet af databasen, når den er hentet.

Vi følger lignende taktikker for at tilføje og slette emner fra databasen. Hver gang genbefolker itemListmed det opdaterede indhold i databasen.

Del II: Elektron

Installation af SQLite3.

Nu hvor vi er færdige med vores frontend, er vi nødt til at oprette Electron-backend. Electron-backend'en håndterer og behandler meddelelser, der sendes fra forsiden, og administrerer sqlite3-databasen.

Vi bruger sqlite3 til vores database og skal installere den.

$ npm install sqlite3 --save

En forhindring, jeg stødte på, mens jeg oprindeligt arbejdede med sqlite3 og Electron, var at sqlites oprindelige binære filer skal kompileres igen til brug med Electron. Electron-Forge skal tage sig af dette for dig. En ting at bemærke, Electron-Forge bruger node-gyp til at kompilere binærfilerne. Du skal muligvis have det korrekt installeret og konfigureret inden brug, hvilket inkluderer installation af Python. Fra nu af bruger node-gyp python 2. Hvis du har flere versioner på din maskine, skal du sikre dig, at den aktuelle build bruger den rigtige.

Opretter forbindelse til databasen.

Now let’s open our src/index.ts file and add some code to connect to the database. The two things we need to do are, connect to the database, and add functions to handle our requests from the renderer process. The finished file looks like this:

An in depth explanation of TypeORM and Electron is beyond the scope of this

guide, so I will only briefly discuss the above file. First we need to import the createConnection class from the TypeORM library. We also need to import or Item schema.

As expected, the createConnection class will create a connection to our database. We pass it a constructor with parameters such as type, database, and entities. Type is a string that describes what type of database we are using. Database is a string that points to the database location. Entities is where we tell TypeORM what schemas to expect. For our purpose: type is ‘sqlite’, Database is ‘./src/assets/data/database.sqlite’, and Entities is our imported Item class.

TypeORM allows you two options when working with database transactions: EntityManager and Repository. Both will give you access to functions for querying the database, without writing the SQL. We create a Repository object with the line itemRepo = connection.getRepository(Item) . This gives us access to transaction methods for our Item table.

Det sidste trin er at oprette funktioner til at håndtere de beskeder, der sendes fra IpcRenderer. Hver funktion bruger det itemRepoobjekt, vi oprettede, til at få adgang til databasen. Efter vellykket afslutning af hver transaktion sender funktionerne den nye tilstand af databasen tilbage til rendereren.

Del III: Kør det!

Med alt komplet kan vi nu køre appen. Electron-Forge håndterer denne proces for os. Alt hvad vi skal gøre er at køre kommandoen:

$ npm run start

Hvis alt er korrekt, åbner Electron din app, og du kan teste den.

Tak for læsningen!