Izomorfna aplikacija s Reactom i Nashornom

1. Pregled

U ovom uputstvu razumjet ćemo što je točno izomorfna aplikacija. Također ćemo razgovarati o Nashornu, JavaScript mehanizmu u paketu s Javom.

Nadalje, istražit ćemo kako možemo koristiti Nashorn zajedno s front-end knjižnicom kao što je React za stvaranje izomorfne aplikacije.

2. Malo povijesti

Tradicionalno su klijentske i poslužiteljske aplikacije napisane na način koji je bio prilično težak na strani poslužitelja. Zamislite PHP kao skriptni mehanizam koji generira uglavnom statični HTML i web preglednike koji ih generiraju.

Netscape je došao s podrška JavaScript-a u njegovom pregledniku još sredinom devedesetih. To je počelo prebacivati ​​dio obrade sa poslužitelja na preglednik na strani klijenta. Dugo su se vremena programeri borili s različitim problemima u vezi s podrškom za JavaScript u web preglednicima.

S rastućom potražnjom za bržim i interaktivnijim korisničkim iskustvom, granica se već pomicala jače. Jedan od najranijih okvira koji je promijenio igru ​​bio je jQuery. Donio je nekoliko korisničkih funkcija i mnogo pojačanu podršku za AJAX.

Ubrzo su se počeli pojavljivati ​​mnogi okviri za front-end razvoj, što je uvelike poboljšalo iskustvo programera. Počevši od AngularJS-a od Googlea, React-a od Facebooka, a kasnije, Vue, počeli su plijeniti pažnju programera.

Uz modernu podršku za preglednike, izvanredne okvire i potrebne alate, plima i oseka uglavnom se preusmjeravaju prema klijentu.

Impresivno iskustvo na sve bržim ručnim uređajima zahtijeva više obrade na strani klijenta.

3. Što je izomorfna aplikacija?

Tako smo vidjeli kako nam front-end okviri pomažu u razvoju web aplikacije u kojoj se korisničko sučelje u potpunosti prikazuje na strani klijenta.

Međutim, također je moguće koristiti isti okvir na strani poslužitelja i generiraju isto korisničko sučelje.

Sada se ne moramo nužno držati rješenja samo na strani klijenta ili samo na poslužitelju. Bolji način je imati rješenje gdje klijent i poslužitelj mogu obraditi isti prednji kod i generiraju isto korisničko sučelje.

Ovaj pristup ima koristi, o čemu ćemo razgovarati kasnije.

Takve web aplikacije nazivaju se izomorfne ili univerzalne. Sada je jezik na strani klijenta najekskluzivniji JavaScript. Stoga, da bi izomorfna aplikacija funkcionirala, moramo koristiti JavaScript i na strani poslužitelja.

Node.js je daleko najčešći izbor za izgradnju aplikacije koja se generira na poslužitelju.

4. Što je Nashorn?

Pa, gdje se Nashorn uklapa i zašto bismo ga trebali koristiti? Nashorn je JavaScript mehanizam pakiran prema zadanim postavkama s Javom. Stoga, ako već imamo pozadinsku web-aplikaciju na Javi i želimo izgraditi izomorfnu aplikaciju, Nashorn je prilično zgodan!

Nashorn je objavljen kao dio Jave 8. Ovo je prvenstveno usredotočeno na omogućavanje ugrađenih JavaScript aplikacija u Javi.

Nashorn kompajlira JavaScript u memoriji u Java Bytecode i prosljeđuje ga JVM-u na izvršenje. To nudi bolje performanse u odnosu na raniji motor Rhino.

5. Stvaranje izomorfne aplikacije

Sad smo prošli dovoljno konteksta. Naša aplikacija ovdje će prikazati Fibonaccijev niz i pružiti gumb za generiranje i prikaz sljedećeg broja u nizu. Stvorimo sada jednostavnu izomorfnu aplikaciju s pozadinskim i prednjim dijelom:

  • Front-end: jednostavni Front-end zasnovan na React.js-u
  • Back-end: Jednostavan back-end Spring Boot-a s Nashornom za obradu JavaScript-a

6. Prednji kraj aplikacije

Koristit ćemo React.js za stvaranje našeg fronta. React je popularna JavaScript knjižnica za izgradnju aplikacija na jednoj stranici. To pomaže nam razgraditi složeno korisničko sučelje na hijerarhijske komponente uz neobavezno stanje i jednosmjerno vezivanje podataka.

React analizira ovu hijerarhiju i stvara memorijsku strukturu podataka koja se naziva virtualni DOM. To pomaže Reactu da pronađe promjene između različitih stanja i napravi minimalne promjene u DOM-u preglednika.

6.1. Komponenta reakcije

Stvorimo našu prvu React komponentu:

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', uspjeh: funkcija (msg) {var series = this.state. podaci; series.push (msg); this.setState ({data: series});} .bind (this), pogreška: 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", value: "Next", onClick: this.handleSubmit})));}} );

Sada, shvatimo što radi gornji kod:

  • Za početak smo definirali komponentu klase u Reactu nazvanu "App"
  • Najviše važna funkcija unutar ove komponente je "render", koji je odgovoran za generiranje korisničkog sučelja
  • Osigurali smo stil className koju komponenta može koristiti
  • Ovdje koristimo stanje komponente za spremanje i prikaz serija
  • Dok se država inicijalizira kao prazan popis, dohvaća podatke prosljeđene komponenti kao oslonac kada se komponenta montira
  • Konačno, klikom na gumb "Dodaj" upućuje se jQuery poziv na REST uslugu
  • Poziv dohvaća sljedeći broj u nizu i dodaje ga stanju komponente
  • Promjena stanja komponente automatski ponovno prikazuje komponentu

6.2. Korištenje komponente React

React traži imenovani element "div" na HTML stranici za usidrenje njegovog sadržaja. Sve što moramo učiniti je osigurati HTML stranicu s ovim elementom "div" i učitati JS datoteke:

   Pozdrav, reagirajte ReactDOM.render (React.createElement (aplikacija, {podaci: [0,1,1]}), document.getElementById ("root")); 

Pa, da vidimo što smo ovdje učinili:

  • Mi uvezao potrebne JS knjižnice, reagiraj, reagiraj-dom i jQuery
  • Nakon toga definirali smo "div" element pod nazivom "root"
  • Također smo uvezli JS datoteku s našom komponentom React
  • Zatim smo komponentu React nazvali "App" s nekim sjemenskim podacima, prva tri Fibonaccijeva broja

7. Pozadina aplikacije

Sada, hajde da vidimo kako možemo stvoriti prikladan back-end za našu aplikaciju. Već smo odlučili koristite Spring Boot zajedno s Spring Webom za izgradnju ove aplikacije. Još važnije, odlučili smo upotrijebite Nashorn za obradu prednjeg dijela koji se temelji na JavaScriptu razvili smo u posljednjem odjeljku.

7.1. Ovisnosti Mavena

Za našu jednostavnu aplikaciju koristit ćemo JSP zajedno s Spring MVC, pa ćemo dodati nekoliko ovisnosti u naš POM:

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

Prva je standardna ovisnost o pokretanju proljeća za web aplikaciju. Drugi je potreban za sastavljanje JSP-ova.

7.2. Web kontroler

Stvorimo sada naš web kontroler, koji će obraditi našu JavaScript datoteku i vratiti HTML pomoću JSP:

@Controller javna klasa MyWebController {@RequestMapping ("/") indeks javnog niza (model karte) baca izuzetak {ScriptEngine nashorn = new ScriptEngineManager (). GetEngineByName ("nashorn"); nashorn.eval (novi FileReader ("static / js / response.js")); nashorn.eval (novi FileReader ("static / js / response-dom-server.js")); nashorn.eval (novi FileReader ("static / app.js")); Objekt html = nashorn.eval ("ReactDOMServer.renderToString (" + "React.createElement (App, {podaci: [0,1,1]})" + ");"); model.put ("content", String.valueOf (html)); return "indeks"; }}

Dakle, što se točno događa ovdje:

  • Dohvaćamo primjerak ScriptEngine tipa Nashorn iz ScriptEngineManager
  • Onda, mi učitati relevantne knjižnice u React, response.js i response-dom-server.js
  • Također učitavamo našu JS datoteku koja ima našu komponentu reagiranja "App"
  • Na kraju, procjenjujemo JS fragment koji stvara reakcijski element s komponentom "App" i nekim podacima o sjemenu
  • To nam daje izlaz React-a, HTML fragmenta kao Objekt
  • Ovaj HTML fragment prosljeđujemo kao podatke relevantnom pogledu - JSP

7.3. JSP

Sada, kako obraditi ovaj HTML fragment u našem JSP-u?

Podsjetimo da React automatski dodaje svoj izlaz imenovanom elementu „div“ - „root“ u našem slučaju. Međutim, na isti ćemo element ručno dodati naš generirani HTML fragment na poslužitelju u našem JSP-u.

Pogledajmo kako JSP izgleda sada:

   Pozdrav React! $ {content} ReactDOM.render (React.createElement (App, {podaci: [0,1,1]}), document.getElementById ("root")); 

Ovo je ista stranica koju smo ranije stvorili, osim činjenice da smo dodali naš HTML fragment u div "root", koji je ranije bio prazan.

7.4. REST kontroler

Konačno, trebamo i REST krajnju točku na poslužitelju koja nam daje sljedeći Fibonaccijev broj u nizu:

@RestController javna klasa MyRestController {@RequestMapping ("/ next / {last} / {secondLast}") javni int indeks (@PathVariable ("last") int last, @PathVariable ("secondLast") int secondLast) baca izuzetak {return zadnji + drugiPosljednji; }}

Ovdje nema ništa posebno, samo jednostavan kontroler Spring REST.

8. Pokretanje aplikacije

Sada, kad smo dovršili svoj front-end kao i naš back-end, vrijeme je da pokrenemo aplikaciju.

Trebali bismo normalno pokrenuti aplikaciju Spring Boot, koristeći klasu bootstrapping:

@SpringBootApplication aplikacija javne klase proširuje SpringBootServletInitializer {@Override zaštićen SpringApplicationBuilder configure (aplikacija SpringApplicationBuilder) {return application.sources (Application.class); } public static void main (String [] args) baca iznimku {SpringApplication.run (Application.class, args); }}

Kada pokrenemo ovaj tečaj, Spring Boot kompajlira naše JSP-ove i čini ih dostupnima na ugrađenom Tomcat-u zajedno s ostatkom web aplikacije.

Ako posjetimo našu stranicu, vidjet ćemo:

Razumijemo slijed događaja:

  • Preglednik zahtijeva ovu stranicu
  • Kada stigne zahtjev za ovu stranicu, Spring web kontroler obrađuje JS datoteke
  • Nashorn engine generira HTML fragment i prosljeđuje ga JSP-u
  • JSP dodaje ovaj HTML fragment u "root" div element, konačno vraćajući gornju HTML stranicu
  • Preglednik prikazuje HTML, a u međuvremenu započinje s preuzimanjem JS datoteka
  • Konačno, stranica je spremna za radnje na strani klijenta - možemo dodati više brojeva u seriju

Ovdje je važno shvatiti što se događa ako React pronađe HTML fragment u ciljnom elementu „div“. U takvim slučajevima, React uspoređuje ovaj fragment s onim što ima i ne zamjenjuje ga ako pronađe čitljiv fragment. To je upravo ono što pokreće prikazivanje na strani poslužitelja i izomorfne aplikacije.

9. Što je još moguće?

U našem jednostavnom primjeru upravo smo ogrebali površinu onoga što je moguće. Front-end aplikacije s modernim JS-okvirima postaju sve moćnije i složenije. Uz ovu dodatnu složenost, postoji mnogo stvari na koje moramo voditi računa:

  • U našoj smo aplikaciji stvorili samo jednu komponentu React, što u stvarnosti to može biti nekoliko komponenata koje tvore hijerarhiju koji prolaze podatke kroz rekvizite
  • Zeljeli bismo stvoriti zasebne JS datoteke za svaku komponentu kako bi se njima moglo upravljati i upravljati njihovim ovisnostima putem "izvoza / zahtjeva" ili "izvoza / uvoza"
  • Štoviše, možda neće biti moguće upravljati stanjem samo unutar komponenata; možda bismo htjeli koristiti državna knjižnica za upravljanje poput Reduxa
  • Nadalje, možda ćemo morati komunicirati s vanjskim uslugama kao nuspojave djelovanja; ovo može zahtijevati da koristimo obrazac poput redux-thunk ili Redux-Saga
  • Što je najvažnije, htjeli bismo iskoristiti JSX, sintaksno proširenje za JS za opis korisničkog sučelja

Iako je Nashorn u potpunosti kompatibilan s čistim JS-om, možda neće podržavati sve gore spomenute značajke. Mnogi od njih zahtijevaju transkompajliranje i polifillove zbog JS kompatibilnosti.

Uobičajena je praksa u takvim slučajevima iskoristite paket modula poput Webpacka ili Rollupa. Ono što uglavnom rade je da obrade sve izvorne datoteke React-a i grupiraju ih u jednu JS datoteku zajedno sa svim ovisnostima. To uvijek zahtijeva da moderni kompajler JavaScript-a poput Babel kompajlira JavaScript kako bi bio kompatibilan s unatrag.

Konačni paket sadrži samo dobri stari JS, koji preglednici mogu razumjeti i kojih se pridržava i Nashorn.

10. Prednosti izomorfne aplikacije

Dakle, puno smo razgovarali o izomorfnim aplikacijama i čak smo sada stvorili jednostavnu aplikaciju. Ali zašto bismo točno uopće trebali brinuti o ovome? Razumijemo neke od ključnih prednosti korištenja izomorfne aplikacije.

10.1. Prikazivanje prve stranice

Jedna od najznačajnijih prednosti izomorfne aplikacije je brže prikazivanje prve stranice. U tipičnoj prikazanoj aplikaciji na strani klijenta, preglednik započinje preuzimanjem svih JS i CSS artefakata.

Nakon toga se učitavaju i počinju prikazivati ​​prvu stranicu. Ako prvu stranicu prikazanu pošaljemo sa strane poslužitelja, to može biti puno brže, pružajući poboljšani korisnički doživljaj.

10.2. SEO prijateljski

Još korist koja se često navodi kod prikazivanja na poslužitelju povezana je sa SEO-om. Smatra se da pretraživački botovi nisu u mogućnosti obraditi JavaScript i stoga ne vide indeksnu stranicu koja se prikazuje na klijentskoj strani kroz knjižnice poput React-a. Stoga je stranica koja se generira na poslužitelju SEO-prijaznija. Vrijedi, međutim, napomenuti da moderni botovi tražilice tvrde da obrađuju JavaScript.

11. Zaključak

U ovom smo tutorijalu prošli kroz osnovne koncepte izomorfnih aplikacija i Nashorn JavaScript mehanizma. Dalje smo istražili kako napraviti izomorfnu aplikaciju s Spring Boot, React i Nashorn.

Zatim smo razgovarali o ostalim mogućnostima proširenja front-end aplikacije i prednostima korištenja izomorfne aplikacije.

Kao i uvijek, kod se može pronaći na GitHub-u.


$config[zx-auto] not found$config[zx-overlay] not found