Izomorf alkalmazás a React és a Nashorn alkalmazásával

1. Áttekintés

Ebben az oktatóanyagban megértjük, mi is pontosan az izomorf alkalmazás. Megbeszéljük a Nashorn-ot, a Java-val együtt szállított JavaScript-motort is.

Ezenkívül megvizsgáljuk, hogyan használhatjuk a Nashorn-ot egy olyan front-end könyvtárral együtt, mint a React egy izomorf alkalmazás létrehozásához.

2. Egy kis történelem

Hagyományosan az ügyfél- és szerveralkalmazásokat olyan módon írták, hogy a szerveroldalon elég nehéz. Gondoljon a PHP-re, mint egy parancsfájl-motorra, amely többnyire statikus HTML-t és webböngészőket generál, amelyek ezeket megjelenítik.

A Netscape a a JavaScript támogatása a böngészőjében a kilencvenes évek közepén. Ez megkezdte a feldolgozás egy részének kiszolgálóoldali és kliensoldali böngésző felé történő áthelyezését. A fejlesztők sokáig különböző problémákkal küzdöttek a böngészők JavaScript támogatásával kapcsolatban.

A gyorsabb és interaktív felhasználói élmény iránti növekvő igény miatt a határ már erősebben feszült. Az egyik legkorábbi keret, amely megváltoztatta a játékot, a jQuery volt. Számos felhasználóbarát funkciót és sokkal továbbfejlesztett támogatást hozott az AJAX számára.

Hamarosan megjelent a front-end fejlesztés sok kerete, ami nagyban javította a fejlesztő tapasztalatait. Kezdve a Google AngularJS-jével, a Facebook-tól a React-rel, később pedig a Vue-val kezdték elragadni a fejlesztők figyelmét.

Modern böngészőtámogatással, figyelemre méltó keretekkel és szükséges eszközökkel, az árapályok nagyrészt az ügyféloldal felé mozdulnak el.

Az egyre gyorsabb kézi eszközök magával ragadó élménye több ügyféloldali feldolgozást igényel.

3. Mi az izomorf alkalmazás?

Tehát láttuk, hogy a front-end keretrendszerek hogyan segítenek nekünk egy webalkalmazás kifejlesztésében, ahol a felhasználói felület teljes mértékben megjelenik az ügyfél oldalon.

Azonban, az is lehetséges, hogy ugyanazt a keretrendszert használja a szerver oldalon és ugyanazt a felhasználói felületet generálja.

Most nem kell feltétlenül ragaszkodnunk a csak kliens vagy csak szerver oldali megoldásokhoz. Jobb módszer, ha van megoldás az ügyfél és a szerver egyaránt feldolgozhatja ugyanazt a kezelői kódot és ugyanazt a felhasználói felületet generálja.

Ennek a megközelítésnek vannak előnyei, amelyeket később megbeszélünk.

Az ilyen webes alkalmazásokat izomorfnak vagy univerzálisnak hívják. Most az ügyféloldali nyelv leginkább kizárólag a JavaScript. Ezért egy izomorf alkalmazás működéséhez a szerver oldalon is használnunk kell a JavaScript-et.

A Node.js messze a leggyakoribb választás a szerveroldali renderelt alkalmazások készítéséhez.

4. Mi a Nashorn?

Szóval, hol fér el Nashorn, és miért használnánk? Nashorn az alapértelmezés szerint Java-val csomagolt JavaScript-motor. Ennélfogva, ha már van webalkalmazás-hátterünk a Java-ban, és izomorf alkalmazást szeretnénk létrehozni, akkor a Nashorn nagyon hasznos!

A Nashorn a Java 8 részeként jelent meg. Ez elsősorban a Java beágyazott JavaScript-alkalmazások engedélyezésére összpontosít.

Nashorn Java memóriamodult fordít a Java Bytecode-ba és átadja a JVM-nek végrehajtásra. Ez jobb teljesítményt nyújt a korábbi motorhoz, a Rhino-hoz képest.

5. Izomorf alkalmazás létrehozása

Most már elég összefüggést éltünk át. Alkalmazásunk itt egy Fibonacci szekvenciát jelenít meg, és egy gombot biztosít a sorozat következő számának előállításához és megjelenítéséhez. Hozzunk létre egy egyszerű izomorf alkalmazást most háttér- és kezelőfelülettel:

  • Kezelőfelület: Egyszerű React.js alapú kezelőfelület
  • Háttér: Egy egyszerű Spring Boot háttér, Nashorn segítségével a JavaScript feldolgozásához

6. Alkalmazás Front-End

Majd használjuk React.js a kezelőfelület létrehozásáért. A React egy népszerű JavaScript könyvtár egyoldalas alkalmazások készítéséhez. Azt segít összetett felhasználói felület hierarchikus összetevőkre bontásában opcionális állapotú és egyirányú adatkötéssel.

A React elemzi ezt a hierarchiát, és létrehoz egy memóriában lévő virtuális DOM nevű adatstruktúrát. Ez segít a React-nek megtalálni a változásokat a különböző állapotok között, és minimálisan változtatni a böngésző DOM-ján.

6.1. React Component

Készítsük el az első React komponensünket:

var App = React.createClass ({displayName: "App", handleSubmit: function () {var last = this.state.data [this.state.data.length-1]; var secondLast = this.state.data [this .state.data.length-2]; $ .ajax ({url: '/ next /' + last + '/' + secondLast, dataType: 'text', siker: function (msg) {var sorozat = this.state. adatok; series.push (msg); this.setState ({data: series});} .bind (this), error: function (xhr, status, err) {console.error ('/ next', status, err .toString ());} .bind (this)});}, componentDidMount: function () {this.setState ({data: this.props.data});}, getInitialState: function () {return {data: []};}, render: function () {return (React.createElement ("div", {className: "app"}, React.createElement ("h2", null, "Fibonacci Generator"), React.createElement ( "h2", null, this.state.data.toString ()), React.createElement ("input", {type: "submit", érték: "Next", onClick: this.handleSubmit})))}}} );

Most megértjük, mit csinál a fenti kód:

  • Először is meghatároztunk egy osztálykomponentust a React-ben, „App” néven.
  • A legtöbb a komponensen belül fontos funkció a „render”, amely felelős a felhasználói felület létrehozásáért
  • Stílust nyújtottunk osztály név hogy az alkatrész használhatja
  • Itt használjuk a komponens állapotát a sorok tárolásához és megjelenítéséhez
  • Míg az állapot inicializálódik üres listaként, az összetevő felhelyezésekor az alkatrésznek propként szállítja az adatokat
  • Végül az „Hozzáadás” gombra kattintva jQuery hívást kezdeményez a REST szolgáltatáshoz
  • A hívás lekéri a sorozat következő számát, és hozzáfűzi az összetevő állapotához
  • Az összetevő állapotának változása automatikusan visszaállítja az összetevőt

6.2. A React Component használata

React keresi egy elnevezett „div” elem a HTML-oldalon annak tartalmának rögzítésére. Csak annyit kell tennünk, hogy biztosítunk egy HTML oldalt ezzel a „div” elemmel, és betöltjük a JS fájlokat:

   Hello React ReactDOM.render (React.createElement (App, {adatok: [0,1,1]}), document.getElementById ("root")); 

Tehát nézzük meg, mit tettünk itt:

  • Mi importálta a szükséges JS könyvtárakat, reagál, reagál-dom és jQuery
  • Ezután definiáltunk egy „root” nevű „div” elemet
  • Importáltuk a JS fájlt is a React komponensünkkel
  • Ezután a React komponenst „App” -nak hívtuk, néhány magadattal, az első három Fibonacci-számmal

7. Alkalmazás-háttér

Most nézzük meg, hogyan hozhatunk létre megfelelő hátteret alkalmazásunkhoz. Már elhatároztuk használja a Spring Boot-ot a Spring Web-szel együtt az alkalmazás felépítéséhez. Ennél is fontosabb, hogy úgy döntöttünk a Nashorn segítségével dolgozza fel a JavaScript-alapú kezelőfelületet az utolsó részben fejlesztettük ki.

7.1. Maven-függőségek

Egyszerű alkalmazásunkhoz a JSP-t a Spring MVC-vel együtt fogjuk használni, ezért hozzáadunk néhány függőséget a POM-hoz:

 org.springframework.boot spring-boot-starter-web org.apache.tomcat.embed tomcat-embed-jasper 

Az első a szokásos tavaszi rendszerindítási függőség egy webalkalmazáshoz. A másodikra ​​a JSP-k összeállításához van szükség.

7.2. Web-vezérlő

Most hozzuk létre webvezérlőnket, amely feldolgozza a JavaScript fájlunkat és HTML-t ad vissza a JSP használatával:

@Controller nyilvános osztály MyWebController {@RequestMapping ("/") nyilvános karakterlánc-index (térképmodell) dobja a Kivételt {ScriptEngine nashorn = new ScriptEngineManager (). GetEngineByName ("nashorn"); nashorn.eval (új FileReader ("static / js / react.js")); nashorn.eval (új FileReader ("static / js / react-dom-server.js")); nashorn.eval (új FileReader ("static / app.js")); Objektum html = nashorn.eval ("ReactDOMServer.renderToString (" + "React.createElement (App, {data: [0,1,1]})" + ");"); model.put ("content", String.valueOf (html)); return "index"; }}

Tehát mi történik itt pontosan:

  • Hívunk egy példányt ScriptEngine típusú Nashorn ScriptEngineManager
  • Aztán mi töltse be a releváns könyvtárakat a React, a React.js és a React-Dom-Server.js fájlokba
  • Betöltjük a JS fájlunkat is, amely az „App” reakciókomponenssel rendelkezik
  • Végül kiértékelünk egy JS fragmenst, amely reakcióelemet hoz létre az „App” komponenssel és néhány magadattal
  • Ez biztosítja a React kimenetét, amely egy HTML töredék Tárgy
  • Ezt a HTML töredéket adatként továbbítjuk a vonatkozó nézethez - a JSP-hez

7.3. JSP

Hogyan dolgozzuk fel ezt a HTML-töredéket a JSP-ben?

Emlékezzünk arra, hogy a React automatikusan hozzáadja a kimenetét egy megnevezett „div” elemhez - esetünkben a „root” -hoz. Azonban, kiszolgálóoldali generált HTML-töredékünket manuálisan hozzáadjuk ugyanahhoz az elemhez a JSP-ben.

Lássuk, hogyan néz ki most a JSP:

   Hello React! $ {content} ReactDOM.render (React.createElement (App, {adatok: [0,1,1]}), document.getElementById ("gyökér")); 

Ez ugyanaz az oldal, amelyet korábban létrehoztunk, kivéve azt a tényt, hogy hozzáadtuk a HTML-töredékünket a "root" div-be, amely korábban üres volt.

7.4. REST vezérlő

Végül szükségünk van egy szerveroldali REST végpontra is, amely megadja a következő Fibonacci számot a sorozatban:

@RestController public class MyRestController {@RequestMapping ("/ next / {last} / {secondLast}") public int index (@PathVariable ("last") int last, @PathVariable ("secondLast") int secondLast) kivételt dob utolsó + másodpercUtolsó; }}

Semmi fantázia itt, csak egy egyszerű Spring REST vezérlő.

8. Az alkalmazás futtatása

Most, hogy befejeztük a kezelőfelületünket és a hátterünket, itt az ideje az alkalmazás futtatásának.

A Spring Boot alkalmazást rendesen el kell indítanunk, a bootstrapping osztály használatával:

A @SpringBootApplication public class alkalmazás kiterjeszti a SpringBootServletInitializer {@Orride védett SpringApplicationBuilder konfigurációt (SpringApplicationBuilder alkalmazás) {return application.sources (Application.class); } public static void main (String [] args) dobja a Kivételt {SpringApplication.run (Application.class, args); }}

Amikor ezt az osztályt vezetjük, A Spring Boot összeállítja JSP -inket, és elérhetővé teszi őket a beágyazott Tomcat-on a többi webalkalmazással együtt.

Most, ha ellátogatunk a webhelyünkre, látni fogjuk:

Értsük meg az események sorrendjét:

  • A böngésző kéri ezt az oldalt
  • Amikor megérkezik az oldalra vonatkozó kérés, a Spring webvezérlő feldolgozza a JS fájlokat
  • A Nashorn motor létrehoz egy HTML töredéket, és továbbítja ezt a JSP-nek
  • A JSP hozzáadja ezt a HTML töredéket a „root” div elemhez, végül visszaadja a fenti HTML oldalt
  • A böngésző rendereli a HTML-t, közben megkezdi a JS fájlok letöltését
  • Végül az oldal készen áll az ügyféloldali műveletekre - további számokat adhatunk hozzá a sorozatból

Itt fontos megérteni, hogy mi történik, ha a React egy HTML töredéket talál a cél „div” elemben. Ilyen esetekben, A React összehasonlítja ezt a töredéket azzal, amije van, és nem helyettesíti, ha olvasható töredéket talál. Pontosan ez biztosítja a szerveroldali megjelenítést és az izomorf alkalmazásokat.

9. Mi lehetséges még?

Egyszerű példánkban éppen felkarcoltuk a lehetséges felületét. A modern JS alapú keretrendszerrel rendelkező front-end alkalmazások egyre erőteljesebbek és összetettebbek. Ezzel a hozzáadott bonyolultsággal sok dologra kell törődnünk:

  • Csak egy React komponenst hoztunk létre alkalmazásunkban, ha a valóságban ez így lehet több hierarchiát alkotó komponens amelyek átadják az adatokat a kellékeken keresztül
  • Szeretnénk hozzon létre külön JS fájlokat minden komponenshez kezelhetőségük és függőségeik kezelése az „export / igény” vagy „export / import” révén
  • Ezenkívül előfordulhat, hogy csak az összetevőkön belül lehet az állapotot kezelni; érdemes használni egy állami menedzsment könyvtár, mint a Redux
  • Ezenkívül előfordulhat, hogy a cselekvések mellékhatásaként kölcsönhatásba kell lépnünk a külső szolgáltatásokkal; ez megkövetelheti tőlünk a felhasználást mint a redux-thunk vagy a Redux-Saga
  • A legfontosabb, hogy szeretnénk kihasználja a JSX-et, a JS szintaxis kiterjesztését a felhasználói felület leírására

Noha a Nashorn teljesen kompatibilis a tiszta JS-sel, lehet, hogy nem támogatja az összes fent említett funkciót. A JS kompatibilitás miatt ezek közül sokan átfordítást és többszörös kitöltést igényel.

A szokásos gyakorlat ilyen esetekben az kihasználhatja a modulcsomagolót, mint a Webpack vagy a Rollup. Elsősorban azt csinálják, hogy az összes React forrásfájlt feldolgozzák, és egyetlen JS fájlba csomagolják, az összes függőséggel együtt. Ehhez mindig szükség van egy olyan modern JavaScript-fordítóra, mint a Babel, hogy a JavaScript visszafelé kompatibilis legyen.

A végső csomagnak csak a jó öreg JS van, amelyet a böngészők meg tudnak érteni, és Nashorn is betartja.

10. Az izomorf alkalmazás előnyei

Tehát nagyon sokat beszéltünk az izomorf alkalmazásokról, és most létrehoztunk egy egyszerű alkalmazást is. De miért is kéne pontosan törődnünk ezzel? Ismerjük meg az izomorf alkalmazás használatának néhány fő előnyét.

10.1. Első oldal megjelenítése

Az izomorf alkalmazás egyik legjelentősebb előnye az első oldal gyorsabb renderelése. A tipikus kliensoldali renderelt alkalmazásban a böngésző az összes JS és CSS műtárgy letöltésével kezdődik.

Ezt követően betöltik és megkezdik az első oldal megjelenítését. Ha az első oldalt kiszolgálói oldalról küldjük, akkor ez sokkal gyorsabb lehet, és fokozott felhasználói élményt nyújt.

10.2. SEO-barát

Egy másik A szerveroldali megjelenítéssel gyakran hivatkozott előny a SEO-hoz kapcsolódik. Úgy gondolják, hogy a keresőrobotok nem képesek feldolgozni a JavaScript-et, és ezért nem látnak egy indexoldalt, amelyet a React-en keresztüli könyvtárakban ügyfél-oldalon rendereltek. A kiszolgálóoldali renderelt oldal tehát SEO-barátabb. Érdemes azonban megjegyezni, hogy a modern keresőmotorok botjai azt állítják, hogy feldolgozzák a JavaScript-et.

11. Következtetés

Ebben az oktatóanyagban áttekintettük az izomorf alkalmazások és a Nashorn JavaScript motor alapfogalmait. Tovább kutattuk, hogyan lehet izomorf alkalmazást létrehozni a Spring Boot, a React és a Nashorn alkalmazással.

Ezután megvitattuk a front-end alkalmazás kiterjesztésének további lehetőségeit és az izomorf alkalmazás használatának előnyeit.

Mint mindig, a kód megtalálható a GitHubon.