Cara membuat aplikasi Electron menggunakan Angular dan SQLite3.

Saya baru-baru ini bereksperimen dengan menukar salah satu aplikasi web Angular saya menjadi aplikasi desktop menggunakan Electron. Saya menghadapi beberapa rintangan di sepanjang jalan, dan memutuskan untuk meletakkan pengalaman saya dalam menulis sehingga dapat membantu orang lain. Sekiranya anda mempunyai rancangan serupa untuk projek anda, saya harap ini mungkin berguna. Kod sumber untuk panduan ini boleh didapati di sini.

Bahagian I: Sudut

Buat Boilerplate.

Demi panduan ini, kami akan membuat aplikasi Angular baru dari awal. Saya akan menggunakan Electron-Forge untuk membuat boilerplate. Electron-Forge menawarkan beberapa templat untuk membuat kod plat boiler, termasuk satu untuk Angular 2. Pasang pertama Electron-Forge CLI.

$ npm i -g electron-forge

Sekarang gunakan CLI untuk membuat papan pemuka aplikasi Angular.

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

The forge CLI akan menambah keperluan asas yang diperlukan untuk menjalankan aplikasi kami. Mari tambahkan beberapa direktori tambahan untuk menempatkan fail pangkalan data kami. Tambahkan direktori aset di bawah src, dan letakkan direktori data dan model di bawahnya.

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

Pokok direktori kini kelihatan seperti ini:

.+-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

Tulis Beberapa Kod.

Sebagai langkah pertama kami, mari tambahkan fail model yang akan sesuai dengan skema pangkalan data kami. Untuk contoh ringkas ini, mari buat kelas yang dipanggil Item. Setiap item akan mengandungi harta id dan nama. Simpan fail dalam projek anda di src/assets/model/item.schema.ts.

Kami akan menggunakan TypeORM untuk pemetaan relasional objek kami. Pasang TypeORM pertama.

$ npm install typeorm --save

Kami akan mengikuti panduan TypeORM untuk membuat skema di sini. Setelah selesai, fail akan kelihatan seperti ini:

TypeORM menggunakan penghias naskhah. Kami menggunakan penghias Entiti untuk menyatakan kelas Item kami sebagai jadual. The @PrimaryGeneratedColumn()penghias mengisytiharkan idsebagai pengenalan yang unik dan memberitahu pangkalan data untuk menjana secara automatik. Kami akan risau untuk membuat pautan ke pangkalan data di kemudian hari.

Buat Perkhidmatan.

Tindakan kami yang seterusnya ialah membuat perkhidmatan aplikasi yang mengendalikan komunikasi dari depan ke hujung belakang. Elektron menyediakan IpcRendererkelas untuk perkara ini sahaja. IpcRendereradalah kelas komunikasi proses antara elektron yang digunakan dalam proses penyaji. Pada dasarnya, kami ingin menggunakan IpcRendereruntuk menghantar mesej ke proses utama Electron. Mesej ini akan menyampaikan maklumat ke proses utama sehingga dapat menangani interaksi pangkalan data.

Melaksanakan IpcRendereradalah di mana kita menemui rintangan pertama kita. Electron bergantung pada kaedah window.require (), yang hanya terdapat di dalam proses penyajian Electron. Ini adalah masalah yang didokumentasikan dengan baik. Untuk mengatasi ini, kita dapat menggunakan pakej ngx-elektron ThornstonHans, yang membungkus semua API Elektron yang terdedah kepada proses penyaji menjadi satu Perkhidmatan Elektron. Anda boleh membaca lebih lanjut mengenai perkara ini di sini.

Sebelum kita dapat menggunakannya ngx-electron, kita perlu memasangnya.

$ npm install ngx-electron --save

Sekarang mari kita buat perkhidmatan untuk mengendalikan IpcRendererkomunikasi kita . Buat src/app.service.ts.

Di app.service.tskami membuat kelas yang dipanggil AppServicedan menambah @Injectable()penghias. Ini membolehkan kita menggunakan suntikan ketergantungan bawaan sudut (DI). Dalam konstruktor kami, kami membuat pemboleh ubah _electronServicejenis tempatan ElectronService. The ElectronServicekelas yang diberikan kepada kami oleh ngrx-electron. Ini membolehkan kita menggunakan IpcRenderkelas Electron tanpa masalah yang disebutkan di atas.

Kami membuat tiga fungsi: satu yang mendapatkan semua Item dalam pangkalan data, satu untuk menambahkan Item ke pangkalan data, dan satu untuk menghapus Item. Setiap fungsi akan mengembalikan Pemerhatian.

Yang dapat dilihat adalah sebahagian dari Perpustakaan RxJs dan menyediakan cara yang baik untuk menangani interaksi pangkalan data kami secara tidak segerak. Anda boleh membaca lebih lanjut mengenai Observables di sini. Perhatikan penggunaan operator Observable ofuntuk menunjukkan bahawa kami membungkus respons kami this._electronService.ipcRenderer.sendSync()sebagai nilai Observable.

Mendaftar Perkhidmatan dan Menulis Komponen.

Dengan perkhidmatan kami yang lengkap, mari masuk src/app.component.tsdan daftarkannya untuk DI. Semasa berada di sana, kami akan menambahkan templat dan fungsi html sederhana untuk menangani peristiwa butang kami.

Pastikan untuk menambah AppServicesebagai penyedia dalam @NgModuleargumen penghias dan juga sebagai pemboleh ubah peribadi dalam AppComponentpembina. Kita juga perlu menambah ElectronServicesebagai penyedia.

Pada permulaan komponen kami, kami ingin memuatkan semua kandungan pangkalan data kami dan memaparkannya. Untuk melakukan ini, kami melanggan addItem()fungsi perkhidmatan yang kami buat. Sekiranya anda ingat, semua fungsi perkhidmatan kami mengembalikan Observable. Untuk mendapatkan data dari pengamatan kami, kami melanggannya, meneruskan fungsi panggilan balik yang berjalan ketika data diterima. Dalam contoh di atas, (items) => (this.itemList = items) akan mengisi pemboleh ubah kelas kami le itemLdengan kandungan pangkalan data setelah ia diambil.

Kami mengikuti taktik serupa untuk menambah dan menghapus item dari pangkalan data. Setiap kali mengisi semula itemListdengan kandungan pangkalan data yang dikemas kini.

Bahagian II: Elektron

Memasang SQLite3.

Sekarang setelah selesai, kita perlu membuat backend Elektron. Backend Elektron akan mengendalikan dan memproses mesej yang dihantar dari depan dan menguruskan pangkalan data sqlite3.

Kami akan menggunakan sqlite3 untuk pangkalan data kami dan perlu memasangnya.

$ npm install sqlite3 --save

Rintangan yang saya hadapi ketika bekerja dengan sqlite3 dan Electron pada mulanya, adalah bahawa binari asli sqlite perlu dikompilasi ulang untuk digunakan dengan Electron. Electron-Forge harus menjaga ini untuk anda. Satu perkara yang perlu diperhatikan, Electron-Forge akan menggunakan node-gyp untuk menyusun binari. Anda mungkin perlu memasangnya dan dikonfigurasikan dengan betul sebelum digunakan, termasuk memasang Python. Setakat ini, node-gyp menggunakan python 2. Sekiranya anda mempunyai banyak versi pada mesin anda, anda mesti memastikan bahawa binaan semasa menggunakan yang betul.

Menyambung ke Pangkalan Data.

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.

The last step is to create functions to handle the messages being sent from the IpcRenderer. Each function will use the itemRepo object we created to access the database. After successful completion of each transaction, the functions will pass the new state of the database back to the renderer.

Part III: Run it!

With everything complete, we can now run the app. Electron-Forge handles this process for us. All we need to do is run the command:

$ npm run start

If everything is correct, Electron will open your app and you can test it out.

Thanks for reading!