Cross-Platt­form-Apps mit Elec­tron

SCREENGUIDE - - Inneres - TEXT: Jens Sie­bert

Er­stel­len Sie Desk­top-Apps mit HTML, CSS und Ja­vaS­cript

Spä­tes­tens das Er­schei­nen von No­de.js hat der Ent­wick­lung von Ja­vaS­cript-Ap­pli­ka­tio­nen, die au­ßer­halb ei­nes Brow­sers lauf­fä­hig sind, den Schre­cken ge­nom­men. Doch kön­nen auf Ba­sis von No­de.js auch Desk­top-Ap­pli­ka­tio­nen mit ei­nem schi­cken User-Interface ent­wi­ckelt wer­den? Und noch da­zu mit den be­kann­ten Web-Tech­no­lo­gi­en und Frame­works?

Genau mit die­sen Fra­gen be­schäf­tig­te sich der Ent­wick­ler Ro­ger Wang im Jahr 2011 am In­tel Open Sour­ce Tech­no­lo­gy Cen­ter. Er schrieb das Mo­dul „no­de-web­kit” (spä­ter „NW.js”) für No­de.js, mit dem die Browser-En­gi­ne Web­Kit in No­de.js-An­wen­dun­gen in­te­griert wer­den konn­te [nwjs.io]. Durch die­se In­te­gra­ti­on war es erst­mals mög­lich, Desk­top-An­wen­dun­gen mit­hil­fe mo­der­ner Web-Tech­no­lo­gi­en zu ent­wi­ckeln. Ei­ner der Mit­ar­bei­ter aus Wangs Team, der Stu­dent Cheng Zhao, wech­sel­te spä­ter zu Git­Hub, wo er an der Ent­wick­lung des Tex­tE­di­tors „Atom” be­tei­ligt war [atom.io]. Die­ser ba­sier­te zu­nächst auf dem „Chro­mi­um Em­bed­ded Frame­work” und soll­te auf „no­de -web­kit” por­tiert wer­den. Wäh­rend der Ar­bei­ten stell­te sich je­doch her­aus, dass die Ar­chi­tek­tur von „no­de-web­kit” ei­ni­ge Schwä­chen auf­wies, wel­che die Por­tie­rung er­schwer­ten. Aus

die­sem Grund ent­schied sich das Atom-Team, ein neu­es Frame­work zu ent­wi­ckeln, das die Vor­tei­le von „no­de-web­kit” mit ei­ner leis­tungs­fä­hi­gen Ar­chi­tek­tur ver­bin­det. So ent­stand im Jahr 2013 die „Atom Shell” (spä­ter „Elec­tron”) als Ba­sis für den „Atom Edi­tor”. Git­Hub stell­te die­ses Frame­work als Open-Sour­ce-Pro­jekt un­ter ei­ner MIT Li­cen­se zur Ver­fü­gung und er­mög­lich­te so die Nut­zung auch in an­de­ren Pro­jek­ten [elec­tron. atom.io] [git­hub.com/elec­tron/elec­tron].

WAS IST ELEC­TRON?

Das Elec­tron-Frame­work be­steht aus zwei Kom­po­nen­ten. Zum ei­nen bil­det No­de.js den Kern des Frame­works als Ba­sis für die Ablauf­um­ge­bung der Elec­tron-Ap­pli­ka­tio­nen auf den un­ter­stütz­ten Platt­for­men (Mac, Win­dows und Li­nux). Zum an­de­ren ent­hält Elec­tron Tei­le der Browser-En­gi­ne Blink, die auch die Grund­la­ge für den Chro­me-Browser von Goog­le bil­det. Genau ge­nom­men nutzt Elec­tron das „Chro­mi­um Con­tent Mo­du­le” (CMM) aus der Blink-En­gi­ne. Die­ses Mo­dul ent­hält je­ne An­tei­le der Brow­serEn­gi­ne, die für die Ver­ar­bei­tung und Darstel­lung von HTML, CSS und Ja­vaS­cript be­nö­tigt wer­den. Ei­ne Elec­tron-Ap­pli­ka­ti­on be­steht im­mer aus min­des­tens zwei Pro­zes­sen. Beim Haupt­pro­zess han­delt es sich um ei­ne klas­si­sche No­de.js-Ap­pli­ka­ti­on mit ei­ner Ja­vaS­cript-Da­tei als Ein­sprung­punkt. Aus die­ser No­de.js-Ap­pli­ka­ti­on her­aus kön­nen ein oder meh­re­re so­ge­nann­te Ren­de­rer-Pro­zes­se ge­star­tet wer­den. Ren­de­rer-Pro­zes­se wer­den im Elec­tron-Jar­gon auch als „Brow­serWin­dow” be­zeich­net. Der Ein­sprung­punkt für den Ren­de­rer-Pro­zess ist ei­ne HTML-Da­tei, die bei der In­stan­zi­ie­rung des Ren­de­rer­Pro­zes­ses an­ge­ge­ben wird.

ENT­WICK­LUNG MIT ELEC­TRON

Um mit der Ent­wick­lung ei­ner Elec­tron-Ap­pli­ka­ti­on star­ten zu kön­nen, müs­sen Sie zu­nächst ei­ni­ge der be­nö­tig­ten Werk­zeu­ge in­stal­lie­ren, wenn Sie noch kei­ne No­de.js-Um­ge­bung ha­ben. Hier­zu ge­hört ne­ben ei­ner ak­tu­el­len Ver­si­on von No­de.js auch der zu­ge­hö­ri­ge Pa­cka­ge-Ma­na­ger npm. Als al­ter­na­ti­ven Pa­cka­geMa­na­ger kön­nen Sie auch yarn ver­wen­den. Nach der Installation der be­nö­tig­ten Werk­zeu­ge le­gen Sie mit­tels „npm in­it” ein neu­es Pro­jekt in­klu­si­ve der Pro­jekt-Da­tei „pa­cka­ge.json” an. An­schlie­ßend fü­gen Sie das Elec­tron-Frame­work zu dem Pro­jekt hin­zu: Die­ses Kom­man­do in­stal­liert Elec­tron als „de­vDe­pen­den­cy” lo­kal in Ih­rem Pro­jekt. Da­bei wird die ex­ak­te Ver­si­on des Frame­works als Ab­hän­gig­keit ge­spei­chert. Dies ist das Vor­ge­hen, das das Team hin­ter Elec­tron emp­fiehlt. Es hat den Vor­teil, dass sich der ak­tu­el­le Stand der Ent­wick­lung im­mer wie­der ex­akt re­pro­du­zie­ren lässt. Soll die ver­wen­de­te Ver­si­on des Elec­tron-Frame­works in dem Pro­jekt ak­tua­li­siert wer­den, so muss dies hän­disch, aber eben auch be­wusst ge­sche­hen. Nach­dem Sie das Elec­tron-Frame­work in­stal­liert ha­ben, müs­sen Sie nun den Ein­sprung­punkt in die Ap­pli­ka­ti­on de­fi­nie­ren. Wie be­reits er­wähnt, han­delt es sich da­bei um ei­ne Ja­vaS­cript-Da­tei. Als Be­zeich­ner hat sich hier der Na­me „main.js” eta­bliert. Die­ser Ein­sprung­punkt wird mit­hil­fe des Ein­trags „main” in der „pa­cka­ge.json”-Da­tei fest­ge­legt: Wei­ter­hin wird emp­foh­len, sämt­li­chen Co­de für die Elec­tronAp­pli­ka­ti­on in ei­nem se­pa­ra­ten Un­ter­ver­zeich­nis na­mens „app” ab­zu­le­gen. Dies hat un­ter an­de­rem den Vor­teil, dass Sie die Ab­hän­gig­kei­ten für die Ap­pli­ka­ti­on in ei­ner ei­ge­nen „pa­cka­ge. json”-Da­tei im „app”-Ver­zeich­nis ver­wal­ten. Dies kann sich bei der Ver­wen­dung gro­ßer Frame­works, wie zum Bei­spiel Re­act oder An­gu­lar, po­si­tiv auf die Wart­bar­keit der Ap­pli­ka­ti­on aus­wirkt. Wenn die not­wen­di­gen Vor­ar­bei­ten ab­ge­schlos­sen sind, kann es an die Ent­wick­lung der ei­gent­li­chen Ap­pli­ka­ti­on ge­hen. Hier­für le­gen Sie zu­nächst die Da­tei „main.js” im „app”-Ver­zeich­nis an und fül­len sie mit Co­de. Der In­halt die­ser Da­tei kann fol­gen­der­ma­ßen aus­se­hen:

Zu­nächst wer­den so­wohl das „app”- als auch das „Brow­serWin­dow”-Ob­jekt aus dem „elec­tron”-Mo­dul ge­la­den. Das „app”-Ob­jekt re­prä­sen­tiert die Ap­pli­ka­ti­on selbst und wird au­to­ma­tisch bei je­dem Start in­stan­zi­iert. Mit­tels des „Brow­serWin­dow”-Ob­jekts wer­den spä­ter ein oder meh­re­re Ren­de­rer-Pro­zes­se ge­star­tet, wel­che die Darstel­lung des UserIn­ter­face über­neh­men. Dies ge­schieht im hier ge­zeig­ten Bei­spiel in­ner­halb der Funk­ti­on „crea­teMainWin­dow”. In die­ser Funk­ti­on wird mit „new Brow­serWin­dow()” ein neu­er Ren­de­rer-Pro­zess an­ge­legt. Das Ob­jekt, das die­sen Pro­zess re­prä­sen­tiert, ent­hält ei­ne Re­fe­renz auf den da­zu­stel­len­den In­halt des Brow­serWin­dows un­ter dem Na­men „we­bCon­tents”. Über die Funk­ti­on „loadURL” die­ser Re­fe­renz le­gen Sie nun den Ein­stiegs­punkt für das User Interface der Ap­pli­ka­ti­on fest. Hier hat sich als Datei­na­me der Be­zeich­ner „in­dex.html” ein­ge­bür­gert. Der Be­zeich­ner „__­dir­na­me” stammt aus der No­de.js-Lauf­zeit­um­ge­bung und lie­fert das ak­tu­el­le Ar­beits­ver­zeich­nis der Ap­pli­ka­ti­on. Nun müs­sen noch ver­schie­de­ne Event-Hand­ler für die Ap­pli­ka­ti­on re­gis­triert wer­den: mainWin­dow.on('clo­sed'): Wird aus­ge­löst, wenn ein Brow­serWin­dow ge­schlos­sen wird. Die Re­fe­renz auf das zu­ge­hö­ri­ge Brow­serWin­dow-Ob­jekt wird dann ge­löscht. • app.on('re­a­dy'): So­bald das Elec­tron-Frame­work die Initia­li­sie­rung der Ap­pli­ka­ti­on be­en­det hat, wird das ‚re­a­dy‘-Event aus­ge­löst. Nun kön­nen z.B. Ren­de­rer-Pro­zes­se er­stellt wer­den. • app.on('win­dow-all-clo­sed'): Wenn al­le Brow­serWin­dow-In­stan­zen ge­schlos­sen wur­den, so wird die Ap­pli­ka­ti­on mit­hil­fe des „win­dow-all-clo­sed”-Events dar­über in­for­miert. Die Ap­pli­ka­ti­on kann nun mit­tels „app.quit()” end­gül­tig be­en­det wer­den. Ei­ne Aus­nah­me bil­det hier das Be­triebs­sys­tem macOS, be­zie­hungs­wei­se des­sen Be­triebs­sys­tem-Platt­form „dar­win”. Hier bleibt die Ap­pli­ka­ti­on trotz­dem ak­tiv, bis sie vom An­wen­der mit der Tas­ten­kom­bi­na­ti­on „cmd + Q” oder über das Ap­pli­ka­ti­ons­Me­nü be­en­det wird. • app.on('ac­tiva­te'): Hier­bei han­delt es sich eben­falls um ein spe­zi­el­les Ver­hal­ten von macOS. Wenn die Ap­pli­ka­ti­on noch ak­tiv ist, aber kei­ne Brow­serWin­dow-In­stan­zen ge­öff­net sind, so wird ein neu­er Ren­de­rer-Pro­zess er­zeugt. Das Grund­ge­rüst der Elec­tron-Ap­pli­ka­ti­on ist da­mit er­stellt. Nun geht es an die Ent­wick­lung des ei­gent­li­chen User-Interface. Hier­für er­stel­len Sie im „app”-Ver­zeich­nis die Da­tei in­dex.html, die als Ein­sprung­punkt für den Ren­de­rer-Pro­zess fest­ge­legt wur­de: Für die ers­ten Schrit­te ge­nügt die­se recht ein­fa­che „in­dex.html”Da­tei. Die Ap­pli­ka­ti­on ist nun be­reit für den ers­ten Start. Als Ver­ein­fa­chung kön­nen Sie in der Da­tei „pa­cka­ge.json” ein Skript hin­ter­le­gen, das die Ap­pli­ka­ti­on star­tet: Der Start der Ap­pli­ka­ti­on er­folgt nun mit­hil­fe des fol­gen­den Kom­man­dos. Das Er­geb­nis sieht dann aus wie in Ab­bil­dung 2. Nach­dem Sie nun das Grund­ge­rüst der Elec­tron-Ap­pli­ka­ti­on er­folg­reich im­ple­men­tiert ha­ben, kön­nen Sie das User-Interface mit­hil­fe von be­kann­ten Web-Tech­no­lo­gi­en und Frame­works wei­ter­ent­wi­ckeln. Denk­bar wä­re zum Bei­spiel die Ver­wen­dung von Kom­po­nen­ten-Frame­works, wie zum Bei­spiel Re­act oder An­gu­lar, um die Ap­pli­ka­ti­on sau­ber zu struk­tu­rie­ren. Zu­sätz­lich kön­nen Frame­works, wie zum Bei­spiel Boot­strap, zum Ein­satz kom­men, um ein re­s­pon­sives Lay­out für das User Interface der Ap­pli­ka­ti­on zu im­ple­men­tie­ren. Im wei­te­ren Ver­lauf die­ses Ar­ti­kels sol­len je­doch ei­ni­ge wei­te­re in­ter­es­san­te Kon­zep­te be­leuch­tet wer­den, die das Elec­tronFrame­work zur Ver­fü­gung stellt.

NO­DE.JS-MO­DU­LE IM REN­DE­RER-PRO­ZESS

Auf­grund der Ar­chi­tek­tur des Elec­tron-Frame­works so­wie der Art und Wei­se, wie No­de.js mit dem Chro­mi­um-Con­tent-Mo­dul ver­knüpft wur­de, ist es mög­lich, No­de.js-Mo­du­le in­ner­halb von Ren­de­rer-Pro­zes­sen zu ver­wen­den. Dies er­öff­net ganz neue Op­tio­nen hin­sicht­lich der Ver­wen­dung von Funk­tio­nen des un­ter­lie­gen­den Be­triebs­sys­tems. Hier­zu ge­hört zum Bei­spiel die Mög­lich­keit, di­rekt auf das Da­tei­sys­tem ei­nes Be­triebs­sys­tems zu­zu­grei­fen bzw. Da­tei­en zu er­stel­len und zu lö­schen. In ei­ner her­kömm­li­chen Web-An­wen­dung, die in der Sand­box ei­nes Brow­sers ab­läuft, wä­re das nicht rea­li­sier­bar. Zur De­mons­tra­ti­on die­ser Mög­lich­kei­ten müs­sen wir zu­nächst die Da­tei in­dex.html in un­se­rem Pro­jekt an­pas­sen. Hier muss nun ei­ne Ja­vaS­cript-Da­tei, die wir in die­sem Bei­spiel „in­dex.js” nen­nen, ein­ge­bun­den wer­den: In­ner­halb der „in­dex.js”-Da­tei be­steht nun die Mög­lich­keit, mit­hil­fe des „re­qui­re”-Be­fehls No­de.js-Mo­du­le zu la­den: In die­sem Be­spiel wird das in No­de.js ent­hal­te­ne Mo­dul „os” ge­la­den, das ver­schie­de­ne Funk­tio­nen zur Ab­fra­ge von Ei­gen­schaf­ten des un­ter­lie­gen­den Be­triebs­sys­tems zur Ver­fü­gung stellt. So­bald die „re­a­dyS­ta­te”-Ei­gen­schaft des HTML-Do­ku­ments auf „com­ple­te” wech­selt, wird über die Funk­ti­on „os.plat­form()” die Be­triebs­sys­tem-Platt­form ab­ge­fragt, auf der die Elec­tronAp­pli­ka­ti­on aus­ge­führt wird. Das Er­geb­nis der Ab­fra­ge wird in ei­nem zu­vor de­fi­nier­ten div-Ele­ment mit der id „os-pla­ce­hol­der” ab­ge­legt. Füh­ren Sie die Ap­pli­ka­ti­on nun aus, wird Ih­nen Ihr Be­triebs­sys­tem an­ge­zeigt, wie zum Bei­spiel „win32” bei Win­dows oder „dar­win” bei macOS (Abb. 3). Selbst­ver­ständ­lich han­delt es sich hier­bei nur um ein sehr ein­fa­ches Bei­spiel. Es il­lus­triert je­doch das sehr ein­fa­che Prin­zip, mit des­sen Hil­fe auch kom­ple­xe­re Sze­na­ri­en, wie zum Bei­spiel Zu­grif­fe auf das Da­tei­sys­tem, rea­li­siert wer­den kön­nen.

INTERPROZESS-KOM­MU­NI­KA­TI­ON

In den bis­her ge­zeig­ten Bei­spie­len wur­de mehr­fach dar­auf ver­wie­sen, dass ei­ne Elec­tron-Ap­pli­ka­ti­on aus min­des­tens zwei Pro­zes­sen, dem Haupt­pro­zess und min­des­tens ei­nem Ren­de­rer-Pro­zess, be­steht. Da die­se Pro­zes­se in völ­lig von­ein­an­der iso­lier­ten Pro­zess­räu­men mit ei­ge­nen Ja­vaS­cript-Kon­tex­ten ab­lau­fen, stellt sich si­cher­lich bald die Fra­ge, ob und wie ein Da­ten­aus­tausch zwi­schen den Pro­zes­sen mög­lich ist. Tat­säch­lich bie­tet Elec­tron zu die­sem Zweck ei­ne API zur Interprozess-Kom­mu­ni­ka­ti­on an. Mit­hil­fe die­ser API kann ein Kom­mu­ni­ka­ti­ons­ka­nal zwi­schen dem Haupt­pro­zess und den Ren­de­rer-Pro­zes­sen eta­bliert wer­den. Ei­ne di­rek­te Kom­mu­ni­ka­ti­on zwi­schen den Ren­de­rer-Pro­zes­sen ist nicht oh­ne Wei­te­res mög­lich, da sich die Ren­de­rer-Pro­zes­se un­ter­ein­an­der nicht ken­nen. Für ei­ne Kom­mu­ni­ka­ti­on zwi­schen den Ren­de­rer-Pro­zes­sen müss­te der Um­weg über den Haupt­pro­zess ge­wählt wer­den, da nur die­sem al­le ak­ti­ven Ren­de­rer-Pro­zes­se be­kannt sind. Ein mög­li­ches An­wen­dungs­sze­na­rio für die Interprozess-Kom­mu­ni­ka­ti­on ist die zen­tra­le Hal­tung von Da­ten für meh­re­re Ren­de­rer­Pro­zes­se. Es kann sich da­bei zum Bei­spiel um Ein­stel­lungs-Da­ten han­deln, die zen­tral vom Haupt­pro­zess ver­wal­tet wer­den. Die Ver­tei­lung der Ein­stel­lungs-Da­ten, so­wie die Be­nach­rich­ti­gung der Ren­de­rer-Pro­zes­se im Fal­le von Än­de­run­gen an die­sen Da­ten kön­nen Sie mit­hil­fe der Interprozess-Kom­mu­ni­ka­ti­on rea­li­sie­ren. Die API für die Interprozess-Kom­mu­ni­ka­ti­on wird in Elec­tron mit­hil­fe der Ob­jekt-In­stan­zen „ip­cMain” für den Haupt­pro­zess und „ip­cRen­de­rer” für al­le Ren­de­rer-Pro­zes­se im­ple­men­tiert. Bei­de Ob­jek­te bie­ten je­weils die Mög­lich­keit, sich mit­hil­fe der „on”Funk­ti­on auf ver­schie­de­ne „Chan­nel-Events” zu re­gis­trie­ren. Eben­so bie­tet das „ip­cRen­de­rer”-Ob­jekt ei­ne „send”-Funk­ti­on an, mit de­ren Hil­fe ein sol­ches „Chan­nel-Event” aus­ge­löst wer­den kann. Zu­sätz­lich kön­nen über ein „Chan­nel-Event” Da­ten zwi­schen den Pro­zes­sen aus­ge­tauscht wer­den.

Es ist eben­falls mög­lich, die Kom­mu­ni­ka­ti­on vom Haupt­pro­zess aus­ge­hend zu in­iti­ie­ren. Hier­für gibt es je­doch kei­ne „send”Funk­ti­on im „ip­cMain”-Ob­jekt. Statt­des­sen ver­wen­den Sie hier die „send”-Funk­ti­on des „we­bCon­tents”-Ob­jek­tes ei­nes Ren­de­rer-Pro­zes­ses. Die Mög­lich­kei­ten der Interprozess-Kom­mu­ni­ka­ti­on zeigt das fol­gen­de, ein­fa­che Bei­spiel. Ziel ist es, die ak­tu­el­le Ver­si­on der Elec­tron-Ap­pli­ka­ti­on im User-Interface dar­zu­stel­len. Die Ap­pli­ka­ti­ons-Ver­si­on kann über die Funk­ti­on „ge­tVer­si­on” des „app”Ob­jek­tes aus­ge­le­sen wer­den, das al­ler­dings nur im Kon­text des Haupt­pro­zes­ses zur Ver­fü­gung steht. Hier­für pas­sen wir zu­nächst die Im­ple­men­tie­rung des Haupt­pro­zes­ses der Ap­pli­ka­ti­on in der Da­tei main.js an: Zu Be­ginn wird das „ip­cMain”-Ob­jekt über den „re­qui­re”-Aus­druck im­por­tiert. In der Funk­ti­on „crea­teMainWin­dow” wird dann ei­ne Re­gis­trie­rung auf das Chan­nel-Event „get-ver­si­on” durch­ge­führt. In­ner­halb der Event­hand­ler-Funk­ti­on er­zeugt die „send”Funk­ti­on ein neu­es Chan­nel-Event, dem die ak­tu­el­le Ver­si­on der Ap­pli­ka­ti­on als Da­ten-Ob­jekt über­ge­ben wird. Ei­ne Re­fe­renz auf den Sen­der des ur­sprüng­li­chen „get-ver­si­on”-Events fin­det sich in der „sen­der”-Ei­gen­schaft des Event-Ob­jek­tes. Die­se Re­fe­renz ent­hält auch die „send”-Funk­ti­on, durch die ein Event an den Sen­der des Events zu­rück­ge­sen­det wer­den kann. In der Im­ple­men­tie­rung des Ren­de­rer-Pro­zes­ses, der sich in der Da­tei „in­dex.js” be­fin­det, müs­sen nun eben­falls ei­ni­ge An­pas­sun­gen vor­ge­nom­men wer­den: Um die Interprozess-API im Ren­de­rer-Pro­zess ver­wen­den zu kön­nen, müs­sen wir das „ip­cRen­de­rer”-Ob­jekt mit­hil­fe des „re­qui­re”-Aus­drucks im­por­tie­ren. So­bald das La­den des UserIn­ter­face ab­ge­schlos­sen ist, wird ein Event-Hand­ler für das Chan­nel-Event „ver­si­on” re­gis­triert. Die­ses Event ist die Ant­wort des Haupt­pro­zes­ses auf ein „get-ver­si­on”-Event. Die vom Haupt­pro­zess an das „ver­si­on”-Event über­ge­be­nen Da­ten, in die­sem Fall die Ver­si­on der Ap­pli­ka­ti­on, fin­den sich im zwei­ten Pa­ra­me­ter der Event­hand­ler-Funk­ti­on („da­ta”) wie­der. Der In­halt die­ses Pa­ra­me­ters wird in die­sem Bei­spiel ein­fach in ei­nen Platz­hal­ter ge­schrie­ben, der in der Da­tei „in­dex.html” mit­tels ei­nes „div”Ele­men­tes an­ge­legt wur­de. Um die Kom­mu­ni­ka­ti­on zwi­schen Ren­de­rer- und Haupt­pro­zess zu in­iti­ie­ren, sen­den wir an­schlie­ßend über die „send”-Funk­ti­on des „ip­cRen­de­rer”-Ob­jek­tes das „get-ver­si­on”-Event an den Haupt­pro­zess. Füh­ren Sie den ge­zeig­ten Co­de aus, so wird die Ver­si­on der Ap­pli­ka­ti­on im User-Interface an­ge­zeigt (Abb. 5). Die­ses recht ein­fa­che Bei­spiel il­lus­triert die Mög­lich­kei­ten, die sich mit­hil­fe der Interprozess-Kom­mu­ni­ka­ti­on er­öff­nen. In­ner­halb des Elec­tron-Frame­works exis­tie­ren noch wei­te­re Mög­lich­kei­ten, zwi­schen Haupt- und Ren­de­rer-Pro­zes­sen zu kom­mu­ni­zie­ren. So lässt sich mit­hil­fe des „re­mo­te”-Ob­jek­tes, das in je­dem Ren­de­rer-Pro­zess zur Ver­fü­gung steht, ei­ne Kom­mu­ni­ka­ti­on im Sti­le ei­nes „Re­mo­te Pro­ce­du­re Calls” eta­blie­ren. Mo­du­le und Funk­tio­nen, die im Kon­text des Haupt­pro­zes­ses de­fi­niert wur­den, kön­nen über das „re­mo­te”-Ob­jekt di­rekt in Ren­de­rer-Pro­zes­se im­por­tiert und dort auf­ge­ru­fen wer­den. Das Elec­tron-Frame­work bie­tet noch vie­le wei­te­re in­ter­es­san­te Kon­zep­te zur Ent­wick­lung von Desk­top-An­wen­dun­gen. Da­zu sei hier auf die aus­führ­li­che Do­ku­men­ta­ti­on auf der Web­sei­te des Elec­tron-Pro­jek­tes ver­wie­sen [elec­tron.atom.io/docs]. Statt­des­sen soll im Fol­gen­den auf die Ver­tei­lung der Desk­top-An­wen­dung ein­ge­gan­gen wer­den. Auch hier­für bie­tet das Elec­tronFrame­work in­ter­es­san­te Mög­lich­kei­ten.

SOFT­WARE-VER­TEI­LUNG MIT ELEC­TRON-BUIL­DER

Bis­her be­steht un­se­re Elec­tron-An­wen­dung le­dig­lich aus ei­ner An­samm­lung von HTML-, Ja­vaS­cript- und CSS-Da­tei­en in ei­nem Pro­jekt­ver­zeich­nis. Wenn die An­wen­dung nun an die End­kun­den ver­teilt wer­den soll, stel­len sich gleich meh­re­re Fra­gen: • Wel­che Be­triebs­sys­te­me nut­zen die End­kun­den? • Wel­che Mög­lich­kei­ten zur Dis­tri­bu­ti­on bie­ten sich auf der je

wei­li­gen Platt­form? • Wird die An­wen­dung über ei­nen App-Sto­re (z.B. den Win­dows

Sto­re) ver­trie­ben? • Wie de­cken Sie mög­lichst vie­le We­ge zur Dis­tri­bu­ti­on mit mög

lichst we­nig Auf­wand ab? Ge­ra­de für den letz­te­ren Punkt hat die Elec­tron-Com­mu­ni­ty ein in­ter­es­san­tes Werk­zeug ent­wi­ckelt: den „elec­tron-buil­der” [goo. gl/EbY6X4]. Da­bei han­delt es sich um ein Soft­ware-Pa­ket, mit dem Sie au­to­ma­ti­siert Dis­tri­bu­ti­ons-Pa­ke­te für al­le un­ter­stütz­ten Platt­for­men des Frame­works er­zeu­gen kön­nen. Die Pa­let­te reicht hier von ein­fa­chen .zip-oder .tar.*-Ar­chi­ven bis hin zu Win­dow­sSe­tups, Disk-Images für macOS oder den Pa­ket-For­ma­ten der di­ver­sen Li­nux-Dis­tri­bu­tio­nen. Zu­sätz­lich kön­nen Sie auch Pa­ke­te für den Win­dows- und den App-Sto­re für macOS er­stel­len. Wei­ter­hin un­ter­stützt „elec­tron-buil­der” au­to­ma­ti­sche Up­dates ei­ner Ap­pli­ka­ti­on mit­hil­fe der In­te­gra­ti­on von „elec­tron-up­dater”. Be­vor wir nun ein Dis­tri­bu­ti­ons-Pa­ket mit­hil­fe des „elec­tron­buil­der” bau­en kön­nen, müs­sen erst noch ei­ni­ge Vor­ar­bei­ten er­le­digt wer­den. Zu­nächst müs­sen wir den „elec­tron-buil­der” in­stal­lie­ren. Dies ge­schieht im Haupt­ver­zeich­nis des Pro­jekts mit­hil­fe von npm: An­schlie­ßend le­gen wir par­al­lel zum „app”-Ver­zeich­nis im Pro­jekt ein Ver­zeich­nis „build” an. Hier wer­den Res­sour­cen für Er­stel­lung der Dis­tri­bu­ti­ons-Pa­ke­te, wie zum Bei­spiel Icons, ab­ge­legt. Je nach zu un­ter­stüt­zen­der Platt­form muss ein fes­ter Satz von Da­tei­en im „build”-Ver­zeich­nis vor­han­den sein. Für Win­dow­sSe­tups be­nö­ti­gen wir zum Bei­spiel ei­ne Da­tei mit dem Na­men „icon.ico”. Die­se muss das Icon der An­wen­dung in ei­ner Grö­ße von min­des­tens 256 x 256 px ent­hal­ten. Für macOS wird ei­ne Da­tei mit dem Na­men „icon.icns” be­nö­tigt. Die­se Da­tei ent­spricht dem App­le-Icon-Image-For­mat und be­inhal­tet das An­wen­dungs-Icon in ver­schie­de­nen Grö­ßen von 16 x 16 px bis hin zu 1.024 x 1.024 px. Beim Bau­en ei­nes Li­nux-Pa­ke­tes ver­wen­det der „elec­tron-buil­der” die Icons aus der Da­tei im For­mat von App­le. Die Icon-Da­tei­en kön­nen Sie mit den ent­spre­chen­den Tools der je­wei­li­gen Platt­form er­stel­len. Zur Ver­ein­fa­chung der Ar­beit kön­nen Sie in der Da­tei „pa­cka­ge.json” des Pro­jek­tes ein wei­te­res Skript an­ge­le­gen, das den „elec­tron-buil­der” auf­ruft: Da­mit sind die Min­dest­an­for­de­run­gen für die Er­stel­lung von Dis­tri­bu­ti­ons-Pa­ke­ten er­füllt. Es gibt noch sehr vie­le wei­te­re Kon­fi­gu­ra­ti­ons­mög­lich­kei­ten für den „elec­tron-buil­der”, die im sehr aus­führ­li­chen Wi­ki auf der Git­Hub-Sei­te des Pro­jek­tes er­läu­tert wer­den. Mit dem fol­gen­den Kom­man­do er­stel­len wir nun ein Dis­tri­bu­ti­ons-Pa­ket für un­se­re Elec­tron-An­wen­dung: Je nach Be­triebs­sys­tem und Hard­ware-Ar­chi­tek­tur er­stellt der „elec­tron-buil­der” nun ein Dis­tri­bu­ti­ons-Pa­ket im Ver­zeich­nis „dist”. So wird auf ei­nem Win­dows-Sys­tem mit 64-Bit ei­ne aus­führ­ba­re Se­t­up-Da­tei für genau die­se Platt­form er­stellt. Mit­hil­fe von Kom­man­do­zei­len-Pa­ra­me­tern kön­nen Sie die Art der zu er­stel­len­den Pa­ke­te steu­ern. So er­stel­len die Pa­ra­me­ter „--mac", „--win" oder „--li­nux" Pa­ke­te für das ent­spre­chen­de Be­triebs­sys­tem, wäh­rend „--ia32” bzw. „--x64” die zu un­ter­stüt­zen­de Hard­ware-Ar­chi­tek­tur be­stim­men. Die Pa­ra­me­ter kön­nen auch be­lie­big kom­bi­niert wer­den. So er­stellt die Kom­bi­na­ti­on „--win --ia32 --x64” ein kom­bi­nier­tes Se­t­up für Win­dows.

FA­ZIT

Mit Elec­tron er­öff­nen sich in­ter­es­san­te neue An­sät­ze zur Ent­wick­lung von Desk­top-An­wen­dun­gen mit­hil­fe be­kann­ter Web­Tech­no­lo­gi­en. Für Ent­wick­lungs­teams, die bis­her über­wie­gend klas­si­sche Web-An­wen­dun­gen ent­wi­ckelt ha­ben, bie­tet sich die Mög­lich­keit, Desk­top-An­wen­dun­gen Platt­form-über­grei­fend und un­ab­hän­gig von in­stal­lier­ten Brow­sern oder an­de­ren Ein­schrän­kun­gen, wie zum Bei­spiel re­strik­ti­ven Richt­li­ni­en für ein Un­ter­neh­mens­netz­werk, zu ent­wi­ckeln. Eben­so ist es mög­lich, be­ste­hen­de Web-Ap­pli­ka­tio­nen als Desk­top-Va­ri­an­te zu ver­öf­fent­li­chen. So las­sen sich Web-Ap­pli­ka­ti­on mit wei­te­ren Mög­lich­kei­ten, wie Off­line-Fä­hig­kei­ten und ei­ner tief­grei­fen­den Desk­top-In­te­gra­ti­on, kom­bi­nie­ren. Be­kann­te Bei­spie­le hier­für sind die Desk­top-Ver­sio­nen von Whats­App und Slack.

Jens Sie­bert ist Soft­ware-Ar­chi­tekt für si­cher­heits­kri­ti­sche Sys­te­me bei ei­nem deut­schen Me­di­zin­tech­nik-Her­stel­ler. In sei­ner Frei­zeit be­schäf­tigt er sich als Ma­ker mit The­men wie dem 3D-Druck und Elek­tro­nik-Ba­s­te­lei­en. Au­ßer­dem hält er Aus­schau nach span­nen­den, neu­en Tech­no­lo­gi­en aus an­de­ren Be­rei­chen der Soft­ware-Ent­wick­lung.

Abb. 1: Pro­zes­se in ei­ner Elec­tron-Ap­pli­ka­ti­on

Abb. 2: Der ers­te Start der „Hel­lo World”-Ap­pli­ka­ti­on

Abb. 3: Ver­wen­dung ei­nes No­de.js-Mo­duls im Ren­de­rer-Pro­zess

Abb. 4: Kom­mu­ni­ka­ti­on zwi­schen Ren­de­rer- und Haupt­pro­zess

Abb. 5: Er­geb­nis der IPC-Kom­mu­ni­ka­ti­on

Twit­ter: @jen­s_­sie­bert Kom­men­tie­ren: screen­gui.de/36/elec­tron

Newspapers in German

Newspapers from Germany

© PressReader. All rights reserved.