måndag 12 maj 2014

JavaScript utveckling med paralleller till Java EE utveckling.

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

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?
JavaJavaScript
Språk:Java 6JavaScript, CofeeScript, Dart.
Modularisering:Java 6Require.js, ECMA 6, Browsify.
Runtime:Java Virtual MachineNode.js, Rhino, Nashorn.
Server runtime: JBoss Enterprice Application Server som implementerar JEE Browsern som implementerar HTML 5.
Dependency managment:MavenBower, Component
MVC:JSF, GWT, Wicket, StrutsAngular.js, Backbone.js, Ember.js etc
Dependency injection:CDIErhålls genom valt MV* ramverk.
Templat ramverk:FaceletsMustach.js, Handlebars.js
Byggramverk:Maven, AntGrunt, Gulp, Component
TDD / BDD:TestNGKarma, Jasmine. Qunit.
Continious Integration:JenkinsJenkins, Travis
Utility projekt:Guava, joda-timejQuery, underscore.js
Scafolding:Maven architype, JBoss forgeYeoman.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


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. 

HTML5 APIs and related technologies


Dependency manger


Java

Maven är rätt bra på att hämta ner projekt från tex Maven central eller privata repos.

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

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.

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]

*Backbone.js
[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.

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

Continious Integration

[TODO:skriv om detta]

Travis.js - Bygger ett node.js projekt. phantom.js - Headless heroku

Utils

Java

Javas brister täcks inte sällan upp av mindre utility projekt så som Googles Guava api eller Joda-time api:et. Community / open source andan i Java driver innovation och utgör en styrka.

JavaScript

Communityn kring JavaScript är fantastisk. Möjligheterna att hitta ett projekt på Github är stor.

* underscore.js
Hjälpfuntioner i huvudsak för collections. Backbone har ett beroende till detta projekt.

* Jquery
DOM manipulerande. Alla använder detta projekt. Ett exempel är Angular som har med ett subset av Jquery.

Scafolding

Scafolding är en envägsprocedur för att snabbt skapa kod för CRUD operationer på angivna entiteter i modellen. Sedan arbeta man vidare med den genererade kodbasen.

Java

Jag har använt Maven arcitype för att göra en trubbig scafolding. Trubbig i den bemärkelse att man inte kan specificera vilka entiteter man vill göra CRUD operationer på utan endast projekt och paketnamn.

Det finns dock ett nytt initiativ med stöd för detta nämligen JBoss Forge.

JavaScript

* Yeoman.js