Iako sam do sada o Ionicu pisao samo u kontekstu mobilnih aplikacija nedavno sam naišao na primjere korištenja Ionica kao cross-platform desktop aplikacije što mi se učinilo zanimljivim pa sam odlučio nešto više saznati o tome i napisati ovaj blog post.
Što je Electron?
Electron je framework za razvoj cross-platform desktop aplikacija koristeći JavaScript, HTML i CSS. S tehnologijama koje koristi jako podsjeća na Ionic, a omogućava razvoj desktop aplikacija koje se mogu pokrenuti na Windows, Mac i Linux platformi.
Priprema Ionic projetka
Za početak ćemo kreirati novi Ionic projekt.
1 2 3 |
$ ionic start Ionic3ElectronApp sidemenu $ cd Ionic3ElectronApp $ ionic serve |
Kada aplikaciju pokrenemo nećemo vidjeti ništa što već ranije nismo vidjeli. Standardna Ionic aplikacija koja se pokreće u web pregledniku kao što je npr. Google Chrome.
Postavljanje Electron projekta
Sada je potrebno dodati Electron unutar našeg Ionic projekta koristeći naredbu:
1 |
$ npm install electron --save |
Sve dalje opisane korake radimo prema službenoj dokumentaciji na adresi https://electron.atom.io/docs/
Sada ćemo kreirati datoteku main.js koja će biti ulazna točka prilikom pokretanja Ionic-Electron aplikacije. Više o ovoj datoteci možete pronaći na adresi https://electron.atom.io/docs/tutorial/quick-start/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
const {app, BrowserWindow} = require('electron') const path = require('path') const url = require('url') // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let win function createWindow () { // Create the browser window. win = new BrowserWindow({width: 800, height: 600}) // and load the index.html of the app. win.loadURL(url.format({ pathname: path.join(__dirname, 'www/index.html'), protocol: 'file:', slashes: true })) // Open the DevTools. win.webContents.openDevTools() // Emitted when the window is closed. win.on('closed', () => { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. win = null }) } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', createWindow) // Quit when all windows are closed. app.on('window-all-closed', () => { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (win === null) { createWindow() } }) // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here. |
Osim te datoteke moramo unutar package.json dodati dvije važne naredbe.
"main": "main.js" služi kako bi se znalo koju datoteku gledati kada se projekt pokrene kao Electron aplikacija.
"start": "electron ." služi kao naredba za pokretanje Electron aplikacije.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
{ "name": "Ionic3ElectronApp", "version": "0.0.1", "author": "Tomislav Stanković", "homepage": "https://www.tomislavstankovic.com", "private": true, "scripts": { "clean": "ionic-app-scripts clean", "build": "ionic-app-scripts build", "lint": "ionic-app-scripts lint", "ionic:build": "ionic-app-scripts build", "ionic:serve": "ionic-app-scripts serve", "start": "electron ." }, "dependencies": { "@angular/common": "4.4.4", "@angular/compiler": "4.4.4", "@angular/compiler-cli": "4.4.4", "@angular/core": "4.4.4", "@angular/forms": "4.4.4", "@angular/http": "4.4.4", "@angular/platform-browser": "4.4.4", "@angular/platform-browser-dynamic": "4.4.4", "@ionic-native/core": "4.3.2", "@ionic-native/splash-screen": "4.3.2", "@ionic-native/status-bar": "4.3.2", "@ionic/storage": "2.0.1", "electron": "^1.7.9", "ionic-angular": "3.8.0", "ionicons": "3.0.0", "rxjs": "5.4.3", "sw-toolbox": "3.6.0", "zone.js": "0.8.18" }, "devDependencies": { "@ionic/app-scripts": "3.0.1", "typescript": "2.3.4" }, "description": "An Ionic project", "main": "main.js" } |
Spremni smo za kreiranje skripte buildElectron.sh koja će obaviti nekoliko radnji automatski tako da ih ne moramo svaki put ručno pokretati.
1 2 3 4 |
ionic cordova build browser --prod rm -rf www/* cp -r platforms/browser/www/* www/ npm start |
I konačno, Ionic-Electron aplikaciju možemo pokrenuti naredbom ./buildElectron.sh
ili dvoklikom na ikonu buildElectron skripte unutar našeg projekta.
nakon čega dobijemo našu Ionic aplikaciju unutar Electrona.
Možete primijetiti da se prilikom pokretanja aplikacije automatski pokrenuo i Developer Tools. To možemo spriječiti ako unutar main.js datoteke zakomentiramo win.webContents.openDevTools().
Dizajn i prilagodba sučelja
Dizajn trenutno kreirane aplikacije prilagođen je mobilnim uređajima i ako ju raširimo preko cijelog ekrana nekog desktop uređaja to neće izgledati lijepo jer će npr. popis stavki ići jedan ispod drugog preko cijelog ekrana umjesto da se fino rasporedi po nekoliko stavki u jedan red.
Ovo ćemo prikazati na primjeru stranice list.html
To ćemo riješiti korištenjem Ionic Grida.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<ion-header> <ion-navbar> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title>List</ion-title> </ion-navbar> </ion-header> <ion-content> <ion-grid> <ion-row> <ion-col *ngFor="let item of items" (click)="itemTapped($event, item)" col-12 col-md-6 col-lg-4 col-xl-3> <ion-card> <ion-card-header>{{item.title}}</ion-card-header> <ion-card-content>{{item.note}}</ion-card-content> </ion-card> </ion-col> </ion-row> </ion-grid> <div *ngIf="selectedItem" padding> You navigated here from <b>{{selectedItem.title}}</b> </div> </ion-content> |
Konačan izgled na većem ekranu je sljedeći
Produkcijska verzija Electron aplikacije
Kada smo zadovoljni s našom aplikacijom možemo kreirati produkcijsku verziju.
Prije nego to napravimo moramo instalirati Electron Packager. To možemo učiniti naredbom $ npm install -g electron-packager
Nakon toga ćemo kreirati produkcijsku verziju Electron aplikacije za Windows OS.
1 |
$ electron-packager . Ionic3ElectronApp --overwrite --platform=win32 --arch=x64 --prune=true --out=release-builds |
Proces kreiranja produkcijske verzije Electron aplikacije za Windows, Mac ili Linux može se olakšati i ubrzati na sljedeći način.
U datoteku package.json dodajemo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "name": "Ionic3ElectronApp", "version": "0.0.1", "author": "Tomislav Stanković", "homepage": "https://www.tomislavstankovic.com", "private": true, "scripts": { "clean": "ionic-app-scripts clean", "build": "ionic-app-scripts build", "lint": "ionic-app-scripts lint", "ionic:build": "ionic-app-scripts build", "ionic:serve": "ionic-app-scripts serve", "start": "electron .", "package-mac": "electron-packager . --overwrite --platform=darwin --arch=x64 --icon=assets/icons/mac/icon.icns --prune=true --out=release-builds", "package-win": "electron-packager . electron-tutorial-app --overwrite --asar=true --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName=\"Electron Tutorial App\"", "package-linux": "electron-packager . electron-tutorial-app --overwrite --asar=true --platform=linux --arch=x64 --icon=assets/icons/png/1024x1024.png --prune=true --out=release-builds" }, |
I onda se proces kreiranja produkcijske verzije Electron desktop aplikacije pokreće sljedećim naredbama:
– Windows OS:
npm run package-win
– Mac:
npm run package-mac
– Linux:
npm run package-linux
Zaključak
Iz ovog ste blog posta mogli vidjeti kako Ionic mobilnu aplikaciju pretvoriti u cross-platform destkop aplikaciju pa iako se to čini zanimljivim i očito da je moguće osobno se ne planiram detaljnije tome posvetiti. Također, ne treba zanemariti niti činjenicu da na tu temu ne postoji dovoljno primjera i dokumentacije.