JavaScript utveckling med paralleller till Java EE utveckling.
JavaScript utvecklingen går i rasande takt. Man hinner inte titta bort förrän något nytt ramverk eller toolkit har bytt ut det man just lärt sig använda.
Man kan dock häva att JavaScript utvecklingen har mognat i takt med att browsern alltmer är att betrakta som en kraftfull utvecklingsplattform samt att man har en headless runtime i Node.js.
“If you can't explain it to a six year old, you don't understand it yourself.” - Albert Einstein
“If you can't explain it to a six year old, you don't understand it yourself.” - Albert Einstein
Jag tänker försöka att dra paralleller mellan JEE utveckling och front-end JavaScript utveckling. Java utveckling har länge adresserat de problem som man tampas med i stora projekt med lång livslängd. Tabellen nedan är essensen i artikeln. Texten som förklarar de individuella delarna kommer jag aldrig få helt klar.
Avsnitten är indelade enligt: Rubrik (generell förklaring), Java (Hur det fungerar i JEE), JavaScript (hur det fungerar... du fattar) samt ett antal * JavaScript projekt som löser uppgiften.
Så vad har du i din Java stack för typisk JEE utveckling?
| Java | JavaScript | |
| Språk: | Java 6 | JavaScript, CofeeScript, Dart. |
| Modularisering: | Java 6 | Require.js, ECMA 6, Browsify. |
| Runtime: | Java Virtual Machine | Node.js, Rhino, Nashorn. |
| Server runtime: | JBoss Enterprice Application Server som implementerar JEE | Browsern som implementerar HTML 5. |
| Dependency managment: | Maven | Bower, Component |
| MVC: | JSF, GWT, Wicket, Struts | Angular.js, Backbone.js, Ember.js etc |
| Dependency injection: | CDI | Erhålls genom valt MV* ramverk. |
| Templat ramverk: | Facelets | Mustach.js, Handlebars.js |
| Byggramverk: | Maven, Ant | Grunt, Gulp, Component |
| TDD / BDD: | TestNG | Karma, Jasmine. Qunit. |
| Continious Integration: | Jenkins | Jenkins, Travis |
| Utility projekt: | Guava, joda-time | jQuery, underscore.js |
| Scafolding: | Maven architype, JBoss forge | Yeoman.js |
Språk
Java
Världens mest använda programmeringsspråk som numera är utsatt för kritik eftersom det var föråldrat (innan Java 8). Java var så deklarativt och icke funktonellt att alternativa språk utvecklas som kompileras till av JVM:en förstålig bytekod. Ett sådant exempel är det pseudofunktionella språket Scala.
TODO: Skriv något om invoke dynamic.
JavaScript
Världens mest använda webbklient språk. Även det är utsatt för kritik som oftast går ut på att det är ett riktigt skitspråk som möjliggör illasinnade språkkonstruktioner. Ett exempel på att lösa detta är CoofeeScript eller Dart som via någon byggprocess kompileras till JavaScript.
Modularisering
I mjukvara som sträcker sig förbi Hello World så vill man bryta ut sin kod i moduler och sub projekt. Man vill även kunna ladda in beroenden till projekt från tredje part.Java
I Java är detta ett mindre problem. Paket och klasser gör det enkelt att avgränsa mjukvarans syfte. Klassladdare laddar gärna jar filer med dess paket och klasser. En Java klass beroende är tydligt specificerade i dess import statements. Om man använder Maven så refereras dessa jar filer till som Maven artifacts. Maven artifacts beroenden är specificerade i en xml fil som heter pom.JavaScript
Här blir det lite värre. Det finns inget standardiserat sätt att tala om vilka beroenden ett JavaScript har. JavaScript körs oftast i browsern som använder det asynkrona http protokollet. Följande problem uppstår: modul A kan ha ett beroende till modul B. Men det finns inget som garanterar att B är laddad när A begär den.Inför ECMA6 som får AMD (Asynchronous Module Definition) native så får vi använda mer "hackish" men fungerande script loaders i browsern.
* Require.js
AMD i browsern. Require laddar och injicerar referenser till klasser eller functioner. Require instansierar inget, det ansvaret har din applikation.
Require.js och Angular.js
* Common.js
AMD i Node.
* browsify.js
Node style i browsern. Känns som en naturlig vinnare, varför ha två olika?
Runtime
Java
JVM är den motor som kör den kompilerade koden.
JavaScript
Någon smarter (Ryan Dahl) tog Chromiums JavaScript motor V8 och skapade ett standalone lager runt detta monster som kom att kallas node. Node är helt asynkron. Den sover aldrig, väntar aldrig på en resurs, hela dess arkitektur är asynkron (reaktive).
Att ha tillgång till en standalone runtime utanför browsern gör flera av de nedan nämnda områdena möjliga att lösa med JavaScript.
Jag kan inte låta bli att nämna den facinerande roll node kan ha som front-end server. Front-end serverns roll är att agera proxy mot tex en Java EE backend som exponerar micro tjänster i form av REST eller JMS. Här get @crichardson en lysande förklaring i ämnet:
Node.JS: The Good Parts? A Skeptic's View
Att ha tillgång till en standalone runtime utanför browsern gör flera av de nedan nämnda områdena möjliga att lösa med JavaScript.
Jag kan inte låta bli att nämna den facinerande roll node kan ha som front-end server. Front-end serverns roll är att agera proxy mot tex en Java EE backend som exponerar micro tjänster i form av REST eller JMS. Här get @crichardson en lysande förklaring i ämnet:
Node.JS: The Good Parts? A Skeptic's View
Server Runtime
Java
Det som vi vanligen kallar JEE (Java Enterprice Enviroment) enviroment implementerar en rad tekniker. Denna runntime implementerar ett antal JEE standarder som exempelvis hanterar transaktioner, persistens och ger dig ett MVC ramverk.
JavaScript
Browsern implementerar likt en JEE server runtime en massa standarder som går under namnet HTML5. Nästan alla dessa standarder styrs av JavaScript. Dagens browsers kan mer ses som en plattform likt JEE. Faktum är att Google nu säljer det som alltid varit Microsofts skräck nämligen Browsern som operativ.
JavaScript
* npm
Npm (Node Package Manager) är ett verktyg för att installera mjukvara till din node installation. En stor fördel med JavaScript utveckling är dess högst levande community. Node.js community är inget undantag med en otrolig flora av moduler. Installationen ev en modul är dessutom otroligt smidig.
NPM basic commands
Package dependencies done right
Några mycket intressanta projekt:
rabbitmq + node.js = rabbit.js
Websocket via socket.io
[TODO:skriv om projekt för att undvika call back hell]
npm index
* Bower.js
* npm
NPM basic commands
Package dependencies done right
Några mycket intressanta projekt:
rabbitmq + node.js = rabbit.js
Websocket via socket.io
[TODO:skriv om projekt för att undvika call back hell]
npm index
* Bower.js
Projekt skapat av Twitter. Laddar per default ner beroenden från github.
RequireJS, Backbone, and Bower Starter Template
* Jam.js
Tänk bara på att ingen av de nämnda projekten löser de transitiva beroenden. Det får du hålla reda på själv.Den avgörande skillnaden mellan Bower och Jam är att Jam inte stöder privata repos. Privata repos är mycket vanligt i enterprise världen.
*WebJars
Maven packages. Används av Spring MVC. Alla vet hur mycket Spring har gett tillbaks till communityn, så denna lösning pratar vi inte om ;-)
http://jroper.github.io/client-side-discipline/#/title
MVC
Java
På denna arena råder trängsel. Orsaken till att det finns så många olika varianter av vy ramverk är flera, men en är att vy lagret är den del som är utsatt för mest förändring drivet av krav.
Om du kör JEE och inte har funderat så mycket själv så använder du JSF (JEE standard) för att uppnå ett användargränssnitt. JSF har state på servern och kommunicerar med den i huvudsak via post. JSF använder autobinding mellan modell och vyn med EL uttryck samt har en riktigt avancerad livscykel för konvertering, validering, modelluppdatering och komponent hantering som få förutom BalusC riktigt förstår.
Det finns dock massor av andra ramverk såsom Spring MVC, Vaadin, GWT och Tapestry. Gemensamt för dessa är att de håller state på servern.
Det finns dock massor av andra ramverk såsom Spring MVC, Vaadin, GWT och Tapestry. Gemensamt för dessa är att de håller state på servern.
JavaScript
Att kraven snabbt på vy-lagret är inget som JavaScript är förskonat från. Även här finns en serie av varianter. Att välja vilket ramverk som passar är en övning i att poängsätta ramverken i linje med de krav applikationen har.
*Angular.js
Populärt MVC ramverk från Google som implementerar en trevlig outo binding mellan modell och vy inte helt olik JSF:s EL uttryck. Angular består av:
- Model
- View
- Controllers som kan liknas vid JSF:s backing beans.
- Directives som kan liknas vi JSF:s ui komponenter.
*Ember.js
[TODO:skriv om detta]
*Flight.js
Open source projekt skapat av Twitter. Event drivet ramverk utvecklat av som tvingar utvecklingen att anamma seperation of concerns väldigt strikt.
*Durandal.js
[TODO:skriv om detta]
[TODO:skriv om detta]
knockout.js vs backbone.js
*Knockout.js
[TODO:skriv om detta]
Dependency Injection (CDI)
Java
I vår JEE runtime så tar vi CDI för givet, men minns innan Spring, när det inte fanns.
JavaScript
[TODO: skriv om detta]
Navigering och Templatramverk
Man vill navigera sig från en vy till ett annat. Användaren klickar på en check out i en webb shop och
förväntar sig att stiga in i ett betalflöde. Som utvecklare så vill man kunna återanvända templat på olika sätt för att värna om en snabb utveckling och enhetlig look n feel.
För att komplicera situationen något så har en vy ofta mer en en uppgift. Kanske visar man upp ett flik system med två flikar, en med användarens senaste köp och den andra med produkterbjudanden.
För att komplicera situationen något så har en vy ofta mer en en uppgift. Kanske visar man upp ett flik system med två flikar, en med användarens senaste köp och den andra med produkterbjudanden.
Java
JSF:s navigeringsmodell är kopplat till vyer. En vy utgörs av en xhtml sida. Mellan vyer sätts navigationsrelger upp och saker händer när användaren klickar sig genom applikationen. Vilken flik som skall visas bestäms av en flagga i backing bönan. Innehållet som visas kan laddas om med AJAX.StaleElementReferenceException
I JSF använder man Facelets för att uppnå templating och återanvändbara ui komponenter. Om man vågar kan man skriva egna full blown JSF komponenter, men det undviker man helst.
JavaScript
Vilket JavaScript MVC ramverk du än väljer så anammar du något som kallas Single Page Application (SPA). Principen som man använder för att lösa problemet kallas routing.I teorin behöver du inte ha mer än en enda index.html. Den sidan används för att ladda ditt MVC ramverk som knådar om din DOM för att visualisera de olika vyer och state i vyer som applikationen stöder. De olika state som applikationen kan befinna sig i och vilken information som då visas bestäms av routing ramverket.
Det scenario att samma vy kan spegla olika state är en first class citizen för MVC ramverken i JavaScript. Faktum är att det kanske bara finns en eller ett fåtal html sidor exponerade för http anrop.
Byggramverk
Java
Mavens bygg process kan gör fina saker som tex att kompilera din kod, köra tester och generera site dokumentation.
JavaScript
Den markanta skillnaden mellan Java och JavaScripts bygghanterare är att i JavaScript:s fall så är det Code over configuration som gäller. Numera är det nog få som vill befatta sig med med XML än vad de måste, så 1 poäng till JavaScript.*Grunt.js
Bygger projektet till någon dist mapp. Man kompilerar inte JavaScript, men man minifierar och kör testerna som du självklart skrivit ;-)
*Gulp.js
Grunts ersättare som arbetar i med strömmar av "tasks".
http://www.100percentjs.com/just-like-grunt-gulp-browserify-now/
Gulp vs Grunt
*r.js (utility för Require.js)
Minify och building tool för require.js. r.js används av Grunt. r.js mergar filer och minifierar js och css:er. r.js kan skruvas i så hårt att man faktiskt aldrig laddar require.js eftersom alla js resurser som behövs på den aktuella sidan är hopslagna till en enda fil.TDD / BDD
Jag älskar TDD men när man förändrar koden så river man ofta sina tester eftersom det inte är lönt att skruva i dem. Kanske är BDD lösningen på det? BDD är i vilket fall som helst mer intresserad av resultatet av en operation givet en viss indata än testteckning på radnivå.Skillnaden mellan TDD och BDD
Java
I Java EE världen är TDD kung. Man använder tex TestNG som har en test runner och ett API som matchar. Dessutom så används ofta Mockito för lite trevlig byte manipulering så att man inte behöver skapa interface och alternativa mockade implementationer förhand.JavaScript
I browservärlden så är BDD mer använt än TDD. Detta beror på att man arbetar väldigt mycket mot DOM:en som slutpunkt vilket gör att lågnivå eller detaljerade tester blir mindre relevanta.*Karma och Jasmine
Testacular numera Karma där Karma är test runner och Jasmine api:et. Testar du med Jasmine så gör du det med scenarios i BDD style.
*Qunit
Qunit är mer av ett TDD api, enklare att börja med och saknar en dedikerad test runner.
http://www.ianlewis.org/en/phantom-qunit-test-runner