Electron: aplicații desktop multiplatformă simplificate
Publicat: 2022-03-11La începutul acestui an, Github a lansat Atom-Shell, nucleul celebrului său editor open-source Atom, și l-a redenumit Electron pentru ocazie specială.
Electron, spre deosebire de alți concurenți din categoria aplicațiilor desktop bazate pe Node.js, aduce propria sa întorsătură acestei piețe deja bine stabilite, combinând puterea lui Node.js (io.js până la versiunile recente) cu Chromium Engine pentru a aduce ne este mai bun din JavaScript atât pentru server, cât și pentru client.
Imaginați-vă o lume în care am putea construi aplicații desktop performante, bazate pe date, pe mai multe platforme, alimentate nu numai de depozitul în continuă creștere de module NPM, ci și de întregul registru Bower pentru a satisface toate nevoile noastre la nivel client.
Introduceți Electron.
În acest tutorial, vom construi o aplicație simplă pentru chei cu parole folosind Electron, Angular.js și Loki.js, o bază de date ușoară și în memorie, cu o sintaxă familiară pentru dezvoltatorii MongoDB.
Codul sursă complet al acestei aplicații este disponibil aici.
Acest tutorial presupune că:
- Cititorul are instalate Node.js și Bower pe mașina lor.
- Sunt familiarizați cu sintaxa de interogare asemănătoare Node.js, Angular.js și MongoDB.
Obținerea Bunurilor
În primul rând, va trebui să obținem binarele Electron pentru a testa aplicația noastră local. Îl putem instala la nivel global și îl putem folosi ca CLI sau îl putem instala local în calea aplicației noastre. Recomand să îl instalați la nivel global, astfel încât să nu fie nevoie să o facem din nou și din nou pentru fiecare aplicație pe care o dezvoltăm.
Vom afla mai târziu cum să ambalăm aplicația noastră pentru distribuție folosind Gulp. Acest proces implică copierea binarelor Electron și, prin urmare, nu are niciun sens să-l instalați manual în calea aplicației noastre.
Pentru a instala Electron CLI, putem introduce următoarea comandă în terminalul nostru:
$ npm install -g electron-prebuilt
Pentru a testa instalarea, tastați electron -h
și ar trebui să afișeze versiunea Electron CLI.
La momentul scrierii acestui articol, versiunea Electron era 0.31.2
.
Configurarea Proiectului
Să presupunem următoarea structură de bază a folderelor:
my-app |- cache/ |- dist/ |- src/ |-- app.js | gulpfile.js
… unde: - cache/ va fi folosit pentru a descărca binarele Electron la construirea aplicației. - dist/ va conține fișierele de distribuție generate. - src/ va conține codul nostru sursă. - src/app.js va fi punctul de intrare al aplicației noastre.
Apoi, vom naviga la folderul src/
din terminalul nostru și vom crea fișierele package.json
și bower.json
pentru aplicația noastră:
$ npm init $ bower init
Vom instala pachetele necesare mai târziu în acest tutorial.
Înțelegerea proceselor electronice
Electron distinge între două tipuri de procese:
- Procesul principal : punctul de intrare al aplicației noastre, fișierul care va fi executat ori de câte ori rulăm aplicația. De obicei, acest fișier declară diferitele ferestre ale aplicației și poate fi utilizat opțional pentru a defini ascultătorii de evenimente globale folosind modulul IPC al Electron.
- Procesul de redare : controlerul pentru o anumită fereastră din aplicația noastră. Fiecare fereastră își creează propriul proces de redare.
Pentru claritatea codului, trebuie utilizat un fișier separat pentru fiecare proces de redare. Pentru a defini procesul principal pentru aplicația noastră, vom deschide
src/app.js
și vom include modulul deapp
pentru a porni aplicația și modululbrowser-window
pentru a crea diferitele ferestre ale aplicației noastre (ambele părți ale miezului Electron), ca atare:
var app = require('app'), BrowserWindow = require('browser-window');
Când aplicația este de fapt pornită, declanșează un eveniment ready
, la care ne putem lega. În acest moment, putem instanția fereastra principală a aplicației noastre:
var mainWindow = null; app.on('ready', function() { mainWindow = new BrowserWindow({ width: 1024, height: 768 }); mainWindow.loadUrl('file://' + __dirname + '/windows/main/main.html'); mainWindow.openDevTools(); });
Puncte cheie:
- Creăm o nouă fereastră prin crearea unei noi instanțe a obiectului
BrowserWindow
. - Ia un obiect ca un singur argument, permițându-ne să definim diferite setări, printre care lățimea și înălțimea implicite a ferestrei.
- Instanța ferestrei are o metodă
loadUrl()
, care ne permite să încărcăm conținutul unui fișier HTML real în fereastra curentă. Fișierul HTML poate fi fie local , fie la distanță . - Instanța ferestrei are o metodă opțională
openDevTools()
, permițându-ne să deschidem o instanță a Chrome Dev Tools în fereastra curentă în scopuri de depanare.
În continuare, ar trebui să ne organizăm puțin codul. Recomand să creați un folder windows/
în folderul nostru src/
și unde putem crea un subfolder pentru fiecare fereastră, ca atare:
my-app |- src/ |-- windows/ |--- main/ |---- main.controller.js |---- main.html |---- main.view.js
… unde main.controller.js
va conține logica „server-side” a aplicației noastre, iar main.view.js
va conține logica „client-side” a aplicației noastre.
Fișierul main.html
este pur și simplu o pagină web HTML5, așa că îl putem începe pur și simplu astfel:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Password Keychain</title> </head> <body> <h1>Password Keychain</h1> </body> </html>
În acest moment, aplicația noastră ar trebui să fie gata de rulare. Pentru a-l testa, putem pur și simplu să introducem următoarele în terminalul nostru, la rădăcina folderului src
:
$ electron .
Putem automatiza acest proces prin definirea scriptului de
start
al fișierului package.son.
Crearea unei aplicații desktop Keychain cu parole
Pentru a construi o aplicație de tip breloc de parole, avem nevoie de: - O modalitate de a adăuga, genera și salva parole. - O modalitate convenabilă de a copia și elimina parolele.
Generarea și salvarea parolelor
Un formular simplu va fi suficient pentru a introduce parole noi. De dragul de a demonstra comunicarea între mai multe ferestre în Electron, începeți prin a adăuga o a doua fereastră în aplicația noastră, care va afișa formularul „inserați”. Deoarece vom deschide și închide această fereastră de mai multe ori, ar trebui să încheiem logica într-o metodă, astfel încât să o putem apela pur și simplu atunci când este necesar:
function createInsertWindow() { insertWindow = new BrowserWindow({ width: 640, height: 480, show: false }); insertWindow.loadUrl('file://' + __dirname + '/windows/insert/insert.html'); insertWindow.on('closed',function() { insertWindow = null; }); }
Puncte cheie:
- Va trebui să setăm proprietatea show la false în obiectul opțiuni al constructorului BrowserWindow, pentru a preveni deschiderea implicită a ferestrei când pornesc aplicațiile.
- Va trebui să distrugem instanța BrowserWindow ori de câte ori fereastra declanșează un eveniment închis .
Deschiderea și închiderea ferestrei „Inserare”.
Ideea este să poți declanșa fereastra „inserare” atunci când utilizatorul final dă clic pe un buton din fereastra „principală”. Pentru a face acest lucru, va trebui să trimitem un mesaj din fereastra principală către Procesul principal pentru a-i solicita să deschidă fereastra de inserare. Putem realiza acest lucru folosind modulul IPC al lui Electron. Există de fapt două variante ale modulului IPC:
- Unul pentru Procesul Principal, permițând aplicației să se aboneze la mesajele trimise din Windows.
- Unul pentru procesul de redare, permițând aplicației să trimită mesaje către procesul principal.
Deși canalul de comunicare al lui Electron este în mare parte unidirecțional, este posibil să accesați modulul IPC al procesului principal într-un proces de redare utilizând modulul de la distanță. De asemenea, Procesul Principal poate trimite un mesaj înapoi către Procesul de redare din care a provenit evenimentul utilizând metoda Event.sender.send().
Pentru a utiliza modulul IPC, trebuie doar să îl avem ca orice alt modul NPM din scriptul nostru principal de proces:
var ipc = require('ipc');
... și apoi se leagă de evenimente cu metoda on()
:
ipc.on('toggle-insert-view', function() { if(!insertWindow) { createInsertWindow(); } return (!insertWindow.isClosed() && insertWindow.isVisible()) ? insertWindow.hide() : insertWindow.show(); });
Puncte cheie:
- Putem numi evenimentul cum vrem, exemplul este doar arbitrar.
- Nu uitați să verificați dacă instanța BrowserWindow este deja creată, dacă nu, atunci instanțiați-o.
- Instanța BrowserWindow are câteva metode utile:
- isClosed() returnează un boolean, indiferent dacă fereastra este sau nu într-o stare
closed
. - isVisible() : returnează un boolean, indiferent dacă fereastra este sau nu vizibilă în prezent.
- show() / hide() : metode convenabile pentru a afișa și a ascunde fereastra.
- isClosed() returnează un boolean, indiferent dacă fereastra este sau nu într-o stare
Acum trebuie de fapt să declanșăm acel eveniment din Procesul de redare. Vom crea un nou fișier script numit main.view.js
și îl vom adăuga la pagina noastră HTML așa cum am face-o cu orice script normal:
<script src="./main.view.js"></script>
Încărcarea fișierului script prin intermediul etichetei
script
HTML încarcă acest fișier într-un context pe partea clientului. Aceasta înseamnă că, de exemplu, variabilele globale sunt disponibile prinwindow.<varname>
. Pentru a încărca un script într-un context pe partea de server, putem folosi metodarequire()
direct în pagina noastră HTML:require('./main.controller.js');
.
Chiar dacă scriptul este încărcat în contextul clientului , putem încă accesa modulul IPC pentru Procesul de redare în același mod în care putem face pentru Procesul principal și apoi trimitem evenimentul nostru ca atare:
var ipc = require('ipc'); angular .module('Utils', []) .directive('toggleInsertView', function() { return function(scope, el) { el.bind('click', function(e) { e.preventDefault(); ipc.send('toggle-insert-view'); }); }; });
Există și o metodă sendSync() disponibilă, în cazul în care trebuie să ne trimitem evenimentele sincron.
Acum, tot ce ne rămâne de făcut pentru a deschide fereastra „inserare” este să creăm un buton HTML cu directiva Angular corespunzătoare pe el:
<div ng-controller="MainCtrl as vm"> <button toggle-insert-view class="mdl-button"> <i class="material-icons">add</i> </button> </div>
Și adăugați acea directivă ca o dependență a controlerului unghiular al ferestrei principale:
angular .module('MainWindow', ['Utils']) .controller('MainCtrl', function() { var vm = this; });
Generarea parolelor
Pentru a menține lucrurile simple, putem folosi modulul uuid
NPM pentru a genera ID-uri unice care vor acționa ca parole în scopul acestui tutorial. Îl putem instala ca orice alt modul NPM, îl putem solicita în scriptul nostru „Utils” și apoi cream o fabrică simplă care va returna un ID unic:
var uuid = require('uuid'); angular .module('Utils', []) ... .factory('Generator', function() { return { create: function() { return uuid.v4(); } }; })
Acum, tot ce ne rămâne de făcut este să creăm un buton în vizualizarea de inserare și să-i atașăm o directivă care va asculta evenimentele de clic pe buton și va apela metoda create():
<!-- in insert.html --> <button generate-password class="mdl-button">generate</button>
// in Utils.js angular .module('Utils', []) ... .directive('generatePassword', ['Generator', function(Generator) { return function(scope, el) { el.bind('click', function(e) { e.preventDefault(); if(!scope.vm.formData) scope.vm.formData = {}; scope.vm.formData.password = Generator.create(); scope.$apply(); }); }; }])
Salvarea parolelor
În acest moment, dorim să ne stocăm parolele. Structura datelor pentru intrările noastre de parolă este destul de simplă:
{ "id": String "description": String, "username": String, "password": String }
Deci, tot ce avem nevoie este un fel de bază de date în memorie care se poate sincroniza opțional cu fișierul pentru backup. În acest scop, Loki.js pare candidatul ideal. Face exact ceea ce avem nevoie pentru scopul acestei aplicații și oferă pe deasupra caracteristica Dynamic Views , permițându-ne să facem lucruri similare cu modulul de agregare al MongoDB.
Vizualizările dinamice nu oferă toate funcționalitățile pe care le oferă modulul de agregare al MongodDB. Vă rugăm să consultați documentația pentru mai multe informații.
Să începem prin a crea un formular HTML simplu:
<div class="insert" ng-controller="InsertCtrl as vm"> <form name="insertForm" no-validate> <fieldset ng-disabled="!vm.loaded"> <div class="mdl-textfield"> <input class="mdl-textfield__input" type="text" ng-model="vm.formData.description" required /> <label class="mdl-textfield__label" for="description">Description...</label> </div> <div class="mdl-textfield"> <input class="mdl-textfield__input" type="text" ng-model="vm.formData.username" /> <label class="mdl-textfield__label" for="username">Username...</label> </div> <div class="mdl-textfield"> <input class="mdl-textfield__input" type="password" ng-model="vm.formData.password" required /> <label class="mdl-textfield__label" for="password">Password...</label> </div> <div class=""> <button generate-password class="mdl-button">generate</button> <button toggle-insert-view class="mdl-button">cancel</button> <button save-password class="mdl-button" ng-disabled="insertForm.$invalid">save</button> </div> </fieldset> </form> </div>
Și acum, să adăugăm logica JavaScript pentru a gestiona postarea și salvarea conținutului formularului:

var loki = require('lokijs'), path = require('path'); angular .module('Utils', []) ... .service('Storage', ['$q', function($q) { this.db = new loki(path.resolve(__dirname, '../..', 'app.db')); this.collection = null; this.loaded = false; this.init = function() { var d = $q.defer(); this.reload() .then(function() { this.collection = this.db.getCollection('keychain'); d.resolve(this); }.bind(this)) .catch(function(e) { // create collection this.db.addCollection('keychain'); // save and create file this.db.saveDatabase(); this.collection = this.db.getCollection('keychain'); d.resolve(this); }.bind(this)); return d.promise; }; this.addDoc = function(data) { var d = $q.defer(); if(this.isLoaded() && this.getCollection()) { this.getCollection().insert(data); this.db.saveDatabase(); d.resolve(this.getCollection()); } else { d.reject(new Error('DB NOT READY')); } return d.promise; }; }) .directive('savePassword', ['Storage', function(Storage) { return function(scope, el) { el.bind('click', function(e) { e.preventDefault(); if(scope.vm.formData) { Storage .addDoc(scope.vm.formData) .then(function() { // reset form & close insert window scope.vm.formData = {}; ipc.send('toggle-insert-view'); }); } }); }; }])
Puncte cheie:
- Mai întâi trebuie să inițializam baza de date. Acest proces implică crearea unei noi instanțe a obiectului Loki, furnizarea căii către fișierul bazei de date ca argument, căutarea dacă acel fișier de rezervă există, crearea lui dacă este necesar (inclusiv colecția „Keychain”) și apoi încărcarea conținutului acest fișier în memorie.
- Putem prelua o anumită colecție din baza de date cu metoda
getCollection()
. - Un obiect de colecție expune mai multe metode, inclusiv o metodă
insert()
, permițându-ne să adăugăm un nou document la colecție. - Pentru a persista conținutul bazei de date în fișier, obiectul Loki expune o metodă
saveDatabase()
. - Va trebui să resetam datele formularului și să trimitem un eveniment IPC pentru a spune Procesului Principal să închidă fereastra odată ce documentul este salvat.
Acum avem un formular simplu care ne permite să generăm și să salvăm noi parole. Să revenim la vizualizarea principală pentru a enumera aceste intrări.
Listarea parolelor
Aici trebuie să se întâmple câteva lucruri:
- Trebuie să putem obține toate documentele din colecția noastră.
- Trebuie să informăm vizualizarea principală ori de câte ori este salvată o nouă parolă, astfel încât să poată reîmprospăta vizualizarea.
Putem prelua lista de documente apelând metoda getCollection()
pe obiectul Loki. Această metodă returnează un obiect cu o proprietate numită data , care este pur și simplu o matrice a tuturor documentelor din acea colecție:
this.getCollection = function() { this.collection = this.db.getCollection('keychain'); return this.collection; }; this.getDocs = function() { return (this.getCollection()) ? this.getCollection().data : null; };
Apoi putem apela getDocs() din controlerul nostru Angular și putem prelua toate parolele stocate în baza de date, după ce o inițializam:
angular .module('MainView', ['Utils']) .controller('MainCtrl', ['Storage', function(Storage) { var vm = this; vm.keychain = null; Storage .init() .then(function(db) { vm.keychain = db.getDocs(); }); });
Un pic de șabloane Angular și avem o listă de parole:
<tr ng-repeat="item in vm.keychain track by $index" class="item--{{$index}}"> <td class="mdl-data-table__cell--non-numeric">{{item.description}}</td> <td>{{item.username || 'n/a'}}</td> <td> <span ng-repeat="n in [1,2,3,4,5,6]">•</span> </td> <td> <a href="#" copy-password="{{$index}}">copy</a> <a href="#" remove-password="{{item}}">remove</a> </td> </tr>
O caracteristică plăcută adăugată ar fi reîmprospătarea listei de parole după introducerea uneia noi. Pentru aceasta, putem folosi modulul IPC al lui Electron. După cum am menționat mai devreme, modulul IPC al procesului principal poate fi apelat într-un proces de redare pentru a-l transforma într-un proces de ascultare, folosind modulul de la distanță. Iată un exemplu despre cum să-l implementați în main.view.js
:
var remote = require('remote'), remoteIpc = remote.require('ipc'); angular .module('MainView', ['Utils']) .controller('MainCtrl', ['Storage', function(Storage) { var vm = this; vm.keychain = null; Storage .init() .then(function(db) { vm.keychain = db.getDocs(); remoteIpc.on('update-main-view', function() { Storage .reload() .then(function() { vm.keychain = db.getDocs(); }); }); }); }]);
Puncte cheie:
- Va trebui să folosim modulul la distanță prin propria metodă
require()
pentru a solicita modulul IPC la distanță din Procesul principal. - Apoi putem configura Procesul nostru de redare ca un ascultător de evenimente prin metoda
on()
și putem lega funcțiile de apel invers la aceste evenimente.
Vizualizarea de inserare va fi apoi responsabilă de expedierea acestui eveniment ori de câte ori este salvat un document nou:
Storage .addDoc(scope.vm.formData) .then(function() { // refresh list in main view ipc.send('update-main-view'); // reset form & close insert window scope.vm.formData = {}; ipc.send('toggle-insert-view'); });
Copierea parolelor
De obicei, nu este o idee bună să afișați parolele în text simplu. În schimb, vom ascunde și vom oferi un buton de confort care să permită utilizatorului final să copieze direct parola pentru o anumită intrare.
Din nou, Electron ne vine în ajutor furnizându-ne un modul clipboard cu metode simple de a copia și lipi nu numai conținut text, ci și imagini și cod HTML:
var clipboard = require('clipboard'); angular .module('Utils', []) ... .directive('copyPassword', [function() { return function(scope, el, attrs) { el.bind('click', function(e) { e.preventDefault(); var text = (scope.vm.keychain[attrs.copyPassword]) ? scope.vm.keychain[attrs.copyPassword].password : ''; // atom's clipboard module clipboard.clear(); clipboard.writeText(text); }); }; }]);
Deoarece parola generată va fi un șir simplu, putem folosi metoda writeText()
pentru a copia parola în clipboard-ul sistemului. Putem apoi actualiza HTML-ul nostru principal și adăuga butonul de copiere cu directiva copy-password
pe el, furnizând indexul matricei de parole:
<a href="#" copy-password="{{$index}}">copy</a>
Eliminarea parolelor
Utilizatorii noștri finali ar putea dori, de asemenea, să poată șterge parolele, în cazul în care acestea devin învechite. Pentru a face acest lucru, tot ce trebuie să facem este să apelăm metoda remove()
din colecția breloc. Trebuie să furnizăm întregul document la metoda „remove()”, ca atare:
this.removeDoc = function(doc) { return function() { var d = $q.defer(); if(this.isLoaded() && this.getCollection()) { // remove the doc from the collection & persist changes this.getCollection().remove(doc); this.db.saveDatabase(); // inform the insert view that the db content has changed ipc.send('reload-insert-view'); d.resolve(true); } else { d.reject(new Error('DB NOT READY')); } return d.promise; }.bind(this); };
Documentația Loki.js afirmă că putem elimina și un document după id-ul său, dar nu pare să funcționeze conform așteptărilor.
Crearea unui meniu desktop
Electron se integrează perfect cu mediul nostru desktop pentru a oferi aplicațiilor noastre o experiență „nativă” pentru utilizator. Prin urmare, Electron vine la pachet cu un modul Meniu, dedicat creării de structuri complexe de meniu desktop pentru aplicația noastră.
Modulul de meniu este un subiect vast și aproape că merită un tutorial propriu. Vă recomand cu tărie să citiți tutorialul de integrare a mediului desktop al Electron pentru a descoperi toate caracteristicile acestui modul.
Pentru scopul acestui tutorial actual, vom vedea cum să creăm un meniu personalizat, să îi adăugăm o comandă personalizată și să implementăm comanda standard Quit.
Crearea și atribuirea unui meniu personalizat aplicației noastre
De obicei, logica JavaScript pentru un meniu Electron ar aparține fișierului de script principal al aplicației noastre, unde este definit Procesul nostru principal. Cu toate acestea, îl putem extrage într-un fișier separat și putem accesa modulul Meniu prin modulul de la distanță:
var remote = require('remote'), Menu = remote.require('menu');
Pentru a defini un meniu simplu, va trebui să folosim metoda buildFromTemplate()
:
var appMenu = Menu.buildFromTemplate([ { label: 'Electron', submenu: [{ label: 'Credits', click: function() { alert('Built with Electron & Loki.js.'); } }] } ]);
Primul element din matrice este întotdeauna folosit ca element de meniu „implicit”.
Valoarea proprietății
label
nu contează prea mult pentru elementul implicit de meniu. În modul dev, va afișa întotdeaunaElectron
. Vom vedea mai târziu cum să atribuim un nume personalizat elementului implicit de meniu în timpul fazei de construire.
În cele din urmă, trebuie să atribuim acest meniu personalizat ca meniu implicit pentru aplicația noastră cu metoda setApplicationMenu()
:
Menu.setApplicationMenu(appMenu);
Maparea comenzilor rapide de la tastatură
Electron oferă „acceleratoare”, un set de șiruri predefinite care se mapează la combinațiile reale de tastatură, de exemplu: Command+A
sau Ctrl+Shift+Z
.
Acceleratorul de
Command
nu funcționează pe Windows sau Linux. Pentru aplicația noastră de breloc de parole, ar trebui să adăugăm un element de meniuFile
, care oferă două comenzi:
- Creare parolă : deschideți vizualizarea de inserare cu Cmd (sau Ctrl) + N
- Ieșire : ieșiți complet din aplicație cu Cmd (sau Ctrl) + Q
... { label: 'File', submenu: [ { label: 'Create Password', accelerator: 'CmdOrCtrl+N', click: function() { ipc.send('toggle-insert-view'); } }, { type: 'separator' // to create a visual separator }, { label: 'Quit', accelerator: 'CmdOrCtrl+Q', selector: 'terminate:' // OS X only!!! } ] } ...
Puncte cheie:
- Putem adăuga un separator vizual prin adăugarea unui element la matrice cu proprietatea
type
setată laseparator
. - Acceleratorul
CmdOrCtrl
este compatibil atât cu tastaturile Mac, cât și cu tastaturile PC - Proprietatea
selector
este doar compatibilă cu OSX!
Stilizarea aplicației noastre
Probabil ați observat în diferitele exemple de cod referințe la nume de clase care încep cu mdl-
. În scopul acestui tutorial, am optat să folosesc cadrul de UI Material Design Lite, dar nu ezitați să folosesc orice cadru UI la alegere.
Orice putem face cu HTML5 poate fi făcut în Electron; țineți cont de dimensiunea în creștere a fișierelor binare ale aplicației și de problemele de performanță rezultate care pot apărea dacă utilizați prea multe biblioteci terțe.
Ambalarea aplicațiilor Electron pentru distribuție
Ai făcut o aplicație Electron, arată grozav, ți-ai scris testele e2e cu Selenium și WebDriver și ești gata să o distribui în lume!
Dar vrei totuși să-l personalizi, să-i dai un nume personalizat, altul decât „Electron” implicit, și poate oferi, de asemenea, pictograme de aplicații personalizate atât pentru platformele Mac, cât și pentru PC.
Clădire cu Gulp
În zilele noastre, există un plugin Gulp pentru orice ne putem gândi. Tot ce trebuia să fac a fost să introduc gulp electron
în Google și, desigur, există un plugin gulp-electron!
Acest plugin este destul de ușor de utilizat atâta timp cât structura folderului detaliată la începutul acestui tutorial a fost menținută. Dacă nu, ar putea fi nevoit să mutați puțin lucrurile.
Acest plugin poate fi instalat ca orice alt plugin Gulp:
$ npm install gulp-electron --save-dev
Și apoi putem defini sarcina noastră Gulp ca atare:
var gulp = require('gulp'), electron = require('gulp-electron'), info = require('./src/package.json'); gulp.task('electron', function() { gulp.src("") .pipe(electron({ src: './src', packageJson: info, release: './dist', cache: './cache', version: 'v0.31.2', packaging: true, platforms: ['win32-ia32', 'darwin-x64'], platformResources: { darwin: { CFBundleDisplayName: info.name, CFBundleIdentifier: info.bundle, CFBundleName: info.name, CFBundleVersion: info.version }, win: { "version-string": info.version, "file-version": info.version, "product-version": info.version } } })) .pipe(gulp.dest("")); });
Puncte cheie:
- folderul
src/
nu poate fi același cu folderul în care se află Gulpfile.js și nici același folder cu folderul de distribuție. - Putem defini platformele către care dorim să exportăm prin intermediul matricei
platforms
. - Ar trebui să definim un folder
cache
, de unde vor fi descărcate binarele Electron, astfel încât să poată fi împachetate cu aplicația noastră. - Conținutul fișierului package.json al aplicației trebuie să fie transmis sarcinii gulp prin proprietatea
packageJson
. - Există o proprietate opțională de
packaging
, care ne permite să creăm și arhive zip ale aplicațiilor generate. - Pentru fiecare platformă, există un set diferit de „resurse de platformă” care poate fi definit.
Adăugarea pictogramelor aplicației
Una dintre proprietățile platformResources
este proprietatea icon
, permițându-ne să definim o pictogramă personalizată pentru aplicația noastră:
"icon": "keychain.ico"
OS X necesită pictograme cu extensia de fișier
.icns
. Există mai multe instrumente online care ne permit să convertim gratuit fișierele.png
în.ico
și.icns
.
Concluzie
În acest articol, am zgâriat doar suprafața a ceea ce poate face Electron. Gândiți-vă la aplicații grozave precum Atom sau Slack ca o sursă de inspirație la care puteți merge cu acest instrument.
Sper că ați găsit acest tutorial util, vă rugăm să nu ezitați să lăsați comentariile voastre și să împărtășiți experiențele voastre cu Electron!