Kuinka rakentaa Electron Desktop -sovellus JavaScript-ohjelmassa: monisäikeinen, SQLite, natiivimoduulit ja muut yleiset kipupisteet

Electronilla on paljon tarjottavaa kehystä työpöytäsovellusten kehittämiselle. Se antaa täyden pääsyn Solmun sovellusliittymään ja ekosfääriin. Se ottaa käyttöön kaikki tärkeimmät käyttöjärjestelmät (yhdellä koodipohjalla). Ja verkkopohjaisen arkkitehtuurinsa ansiosta voit käyttää CSS: n uusimpia ominaisuuksia kehittyneiden käyttöliittymien luomiseen.

On paljon artikkeleita, jotka käsittelevät pääsyä Electroniin, mutta vähemmän omistettu SQLiten käyttämiseen tai monisäikeisiin toimintoihin. Tarkastellaan, kuinka Electronin avulla voidaan rakentaa sovelluksia, jotka käsittelevät suuria tietomääriä tai suorittavat paljon tehtäviä.

Käsittelemme erityisesti:

  • Kuinka Electron toimii (lyhyesti) ja miten sen arkkitehtuuri vaikuttaa siihen, mitä voimme tehdä
  • Monisäikeinen
  • Käyttämällä paikallisia tietokantoja, kuten SQLite, tai kirjoittamalla mihin tahansa tiedostoon Electron-sovelluksessa
  • Alkuperäiset moduulit
  • Muutama gotcha olla tietoinen
  • Pakkaamalla sovellus natiivimoduuleilla

Kuinka Electron toimii - lyhennetty

On syytä toistaa Electronin arkkitehtuurin keskeiset periaatteet. Elektronisovellus koostuu vähintään kahdesta prosessista. Pääkierre on pääsy sovellukseesi ja tekee kaiken tarvittavan työn renderöintiprosessin (tai -prosessien) näyttämiseksi käyttäjille. Pääprosessissa voi olla vain yksi esiintymä.

Renderer-prosessit käyttävät Chromiumia sovelluksesi hahmontamiseen. Aivan kuten kukin välilehti toimii omassa prosessissaan, niin myös kukin renderöijä. Ne ladataan BrowserWindow-konstruktorin loadURL-menetelmällä, jonka on osoitettava paikalliseen tai etähallinta-HTML-tiedostoon. Tämä tarkoittaa, että ainoa tapa käynnistää renderöintiprosessi on käyttää HTML-tiedostoa merkinnänä.

Electronin arkkitehtuurin varoitukset

Electronin yksinkertaisuus on yksi sen suurimmista voimista. Pääprosessisi tekee tarvittavat määritykset ja siirtää sitten HTML-tiedoston tai URL-osoitteen renderöintiprosessiin. Tämä tiedosto voi tehdä mitä tahansa tavallinen verkkosovellus - ja olet hyvä siirtyä sieltä.

Mutta se, että voi olla vain yksi pääprosessi, tekee epäselväksi kuinka monisäikeisyys toteutetaan. Electronin dokumentaatio viittaa siihen, että renderöintiprosessit on suunniteltu tiukasti käyttöliittymien renderointitehtäviin (mikä, kuten näemme, ei ole totta).

On tärkeää tietää, että minkä tahansa laskennallisesti intensiivisen tekeminen pääprosessissa hidastaa (tai jäädyttää) renderöintiprosessejasi. On kriittistä, että kaikki laskennallisesti intensiivinen työ siirretään päälangasta. On parasta jättää se yksinomaan tehtäväksi tehdä kaikki tarvittavat renderöintiprosessien aloittamiseksi. Koska emme voi tehdä intensiivistä työtä samalla renderöintiprosessilla, joka tekee sovelluksen käyttöliittymän (koska tämä vaikuttaa myös käyttöliittymään), tarvitsemme toisen lähestymistavan.

Monisäikeinen

Electronissa on kolme yleistä lähestymistapaa monisäikeisyyteen:

  • Käytä verkkotyöntekijöitä
  • Haaroita uusia prosesseja tehtävien suorittamiseen
  • Suorita (piilotetut) renderöintiprosessit työntekijöinä

Verkkotyöntekijät

Koska Electron on rakennettu Chromiumin päälle, kaikki, mikä voidaan tehdä selaimella, voidaan tehdä renderöintiprosessissa. Tämä tarkoittaa, että voit käyttää verkkotyöntekijöitä intensiivisten tehtävien suorittamiseen erillisissä säikeissä. Tämän lähestymistavan etuna on yksinkertaisuus ja isomorfismin säilyttäminen verkkosovelluksen kanssa.

On kuitenkin olemassa yksi erittäin suuri huomautus - et voi käyttää natiivimoduuleja. Teknisesti voit, mutta se saa sovelluksesi kaatumaan. Tämä on merkittävä ongelma, koska kaikki monisäikeitä tarvitsevat sovellukset saattavat joutua käyttämään myös natiivimoduuleja (kuten node-sqlite3).

Uusien prosessien haaroittaminen

Electron käyttää Solmua ajonaikana, mikä tarkoittaa, että sinulla on täysi pääsy sisäänrakennettuihin moduuleihin, kuten klusteriin. Uudet prosessit voidaan haaroittaa tehtävien suorittamiseen pitämällä intensiivinen työ poissa päälangasta.

Pääasia on, että toisin kuin renderöintiprosessit, aliprosessit eivät voi käyttää menetelmiä Electron-kirjastosta. Tämä pakottaa sinut ylläpitämään viestintäkanavaa pääprosessin kanssa IPC: n kautta. Renderer-prosessit voivat etämoduulin avulla kertoa pääprosessille vain päätehtävien suorittamisen ilman tätä ylimääräistä vaihetta.

Toinen ongelma on, että jos käytät ES-moduuleja tai JavaScriptin TC39-ominaisuuksia, sinun on varmistettava, että käytät skripteistäsi lähetettyjä versioita. Sinun on myös sisällytettävä nämä pakattuun sovellukseesi. Tämä ongelma vaikuttaa kaikkiin prosesseja haarautuviin Node-sovelluksiin, mutta se lisää uuden monimutkaisuuden kerroksen rakennusprosessiin. Se voi myös olla hankalaa, kun sovelluksen pakkaamisen vaatimukset tasapainotetaan kehitystyökalujen kanssa, jotka käyttävät ominaisuuksia, kuten suoralataus.

Renderöintiprosessien käyttö työntekijän ketjuina

Renderer-prosesseja pidetään tavanomaisesti käyttöliittymän hahmottamiseen. He eivät kuitenkaan ole sidoksissa tähän ainoaan tehtävään. Ne voidaan piilottaa ja suorittaa taustalla määrittämällä BrowserWindow'lle välitetty näyttölippu.

Tällä on monia etuja. Toisin kuin verkkotyöntekijät, sinulla on vapaus käyttää natiivimoduuleja. Ja toisin kuin haarautuneissa prosesseissa, voit silti käyttää elektronikirjastoa kertomaan pääprosessille esimerkiksi avata valintaikkuna tai luoda käyttöjärjestelmän ilmoituksia.

Yksi haaste Electronia käytettäessä on IPC. Vaikka se onkin yksinkertainen, se vaatii huomattavan määrän kattilalevyä ja aiheuttaa vaikeuksia virheenkorjauksessa suurelle määrälle tapahtumakuuntelijoita. Se on myös toinen asia, joka sinun on testattava. Käyttämällä renderöintiprosessia työntekijän säikeenä voit kiertää tämän kokonaan. Aivan kuten palvelimen kanssa, voit kuunnella paikallista porttia ja vastaanottaa pyyntöjä, jolloin voit käyttää työkaluja, kuten GraphQL + React Apollo. Voit myös käyttää verkkopistokkeita reaaliaikaiseen viestintään. Toinen bonus on, että sinun ei tarvitse käyttää ipcRendereria, ja voit pitää Electron- ja verkkosovelluksesi isomorfisina (jos haluat käyttää jaettua koodipohjaa työpöydälle ja verkkosovellukselle).

Edistyneissä käyttötapauksissa tämä lähestymistapa voidaan yhdistää klustereihin, jotta saat parhaan mahdollisen hyödyn kaikista maailmoista. Ainoa haittapuoli on, että sinun on annettava HTML-tiedosto työntekijän renderöintiprosessien merkinnäksi (joka tuntuu olevan jotain hakkerointia).

Kuinka käyttää SQLite-ohjelmaa (tai mitä tahansa mitä kirjoitat)

Valtionhallinnassa on useita lähestymistapoja, jotka eivät vaadi natiivimoduuleja. Esimerkiksi koko tilasi käsittely renderöinnin yhteydessä Reduxin kanssa.

Kuitenkin, jos sinun on käsiteltävä suuria tietomääriä, se ei riitä. Tarkastelemme erityisesti SQLiten käyttöä Electron-sovelluksessa.

Electron-sovelluksen asentamiseksi sinun on ensin pakattava se. Tätä varten on käytettävissä useita työkaluja - suosituin on Electron Builder. Electron käyttää ASAR-arkistomuotoa niputtamaan sovelluksesi yhteen, pakkaamattomaan tiedostoon. ASAR-arkistot ovat vain luku -tilassa, joten et voi kirjoittaa niihin mitään tietoja. Tämä tarkoittaa sitä, että et voi sisällyttää tietokantaa ASAR-arkistoosi muun koodisi kanssa (elektroninrakentajalla tämä olisi "tiedostot" -kohdassa).

Sen sijaan sisällytä tietokanta elektronipakettisi Resurssit-hakemistoon. Pakatun Electron-sovelluksen tiedostorakenne ja tietokannan sijoituspaikka näkyvät alla:

Pakattu ASAR-arkisto nimeltä app.asar on ./Contents/Resources. Voit sijoittaa tietokannan tai minkä tahansa tiedoston, johon haluat kirjoittaa, mutta sisällyttää pakattuun sovellukseen, samaan hakemistoon. Tämä voidaan saavuttaa Electron Builderilla käyttämällä “extraResources” -määritystä.

Toinen tapa on luoda tietokanta kokonaan toiseen hakemistoon. Mutta sinun on otettava huomioon tämän tiedoston poistaminen kaikilla alustoilla, jos käyttäjät päättävät poistaa sovelluksesi.

Pakkaus alkuperäisillä moduuleilla

Valtaosa Node-moduuleista on JavaScript-kirjoitettuja komentosarjoja. Alkuperäiset moduulit ovat moduuleja, jotka on kirjoitettu C ++: lla ja joilla on sidoksia käytettäväksi Noden kanssa. Ne toimivat liitäntänä muihin kirjastoihin, jotka on kirjoitettu C / C ++: lla, ja ne on yleensä konfiguroitu kääntämään asennuksen jälkeen.

Matalan tason moduuleina ne on koottava kohdearkkitehtuureille ja käyttöjärjestelmille. Windows-koneelle käännetty natiivimoduuli ei toimi Linux-koneessa - vaikka tavallinen moduuli toimisi. Tämä on ongelma Electronille, koska meidän on lopulta pakattava kaikki .dmg (OSX), .exe (Windows) tai .deb (Linux) suoritettavaan tiedostoon.

Alkuperäisiä moduuleja käyttävät elektronisovellukset on pakattava järjestelmään, johon ne kohdistetaan. Koska haluat automatisoida tämän prosessin CI / CD-putkessa, joudut rakentamaan alkuperäiset riippuvuutesi ennen pakkaamista. Tämän saavuttamiseksi voit käyttää Electron-tiimin kehittämää työkalua nimeltä electron-rebuild.

Jos kehität ei-kaupallista avoimen lähdekoodin projektia, voit rakentaa, testata ja ottaa sovelluksesi käyttöön ilmaiseksi TravisCI: n (Linux, OSX) ja Appveyorin (Windows) avulla.

Tämän määrittäminen voi olla hankalaa, jos sinulla on integraatiotestejä, koska sinun on asennettava tietyt riippuvuudet, jotta päättömät testit toimisivat. Esimerkkikokoonpano OSX: lle ja Linuxille TravisCI: n kanssa löytyy täältä ja esimerkki Appveyor-konfiguraatiosta täältä (nämä esimerkit perustuvat elektroni-reaktiokattilaprojektin kokoonpanoon, lisäämällä OSX: n ja käyttöönoton).

Gotchas

Kun Electron-sovelluksesi on pakattu, jotkin Solmun sisäänrakennetut poluihin liittyvät ominaisuudet eivät välttämättä toimi odotetulla tavalla eivätkä käyttäydy samalla tavalla kuin käyttäessäsi sovellusta palvelemaan ennalta rakennettua binaaria.

Muuttujat, kuten __hakunimi, __tiedostonimi ja menetelmät, kuten process.cwd, eivät toimi odotetusti pakatussa sovelluksessa (katso ongelmat täällä, täällä ja täällä). Käytä sen sijaan app.getAppPath.

Viimeinen huomautus pakkauksista

Kun kehität Electron-sovellusta, saatat haluta käyttää sekä tuotantotilaa (yhdistetyn koodin tarjoaminen valmiiksi kootulla binaarilla) että kehitystilaa (käyttäen webpack-dev-server tai webpack-serve tiedostojen katseluun).

Pitääksesi mielesi yllä, rakenna ja palvele nippuja samasta hakemistosta kuin lähdekoodisi. Tämä tarkoittaa, että kun valitset nämä tiedostot pakkaamista varten, kaikki tiedostopolun oletukset pysyvät yhtenäisinä kaikissa tiloissa ja paketissasi.

Ainakin pääprosessisi on osoitettava renderöintiprosessisi HTML-tiedoston tiedostopolulle. Jos siirrät tämän tiedoston toiseen hakemistoon osana rakennusprosessia, sinun on pakko ylläpitää tiedostorakenteen oletuksia, ja tästä voi tulla nopeasti toinen verotuksellinen monimutkaisuus, jota sinun on ylläpidettävä.

Pakattujen sovellusten virheellisiin tiedostopolkuihin liittyvien ongelmien virheenkorjaus on paljolti kokeilu ja virhe.

Yhteenveto

Electronissa on useita lähestymistapoja monisäikeisiin. Verkkotyöntekijät ovat käteviä, mutta heiltä puuttuu kyky käyttää natiivimoduuleja. Uusien prosessien haarautuminen toimii samalla tavalla kuin Solmessa, mutta kykenemättömyys käyttää Electron-kirjastoa pakottaa IPC: n käytön yleisiin tehtäviin ja voi nopeasti monimutkaistua. Renderöintiprosessien käyttäminen työntekijöinä antaa kaikkien käytettävissä olevien solmupalvelintyökalujen täyden tehon korvaamaan IPC-yhteyden, samalla kun säilytetään pääsy natiivimoduuleihin ja -menetelmiin Electron renderer -kirjastosta.

Koska Electron pakkaa tiedostot vain luku-ASAR-arkistoon, mitään tiedostoja, joihin meidän on kirjoitettava (kuten SQLite-tietokanta), ei voida sisällyttää. Sen sijaan ne voidaan sijoittaa Resurssit-hakemistoon, missä ne jäävät pakattuun sovellukseen.

Lopuksi, ole tietoinen siitä, että paketoidussa sovelluksessa jotkut Solmun ominaisuudet eivät toimi odotetulla tavalla. Ja mielen selvyyden vuoksi sovita pakatun sovelluksen tiedostorakenne lähdekoodiin.