npm install -g coffee-script – @timglabisch – wer nutzt



npm install -g coffee-script – @timglabisch – wer nutzt

1 0


slides_coffeescript


On Github timglabisch / slides_coffeescript

npm install -g coffee-script

@timglabisch

bei fragen - fragen! ;)

wer nutzt

- CoffeeScript?

- JavaScript?

- "oop"?

... compile to JavaScript ...?

  • Am Anfang die gewohnte Frage, ....
  • Wer nutzt CoffeeScript?
  • wer könnte sich vorstellen morgen CoffeeScript zu nutzen?
  • Wer nutzt Javascript?
  • Wer scheibt oop Javascript?
  • Wer nutzt Gwt, Dart, Typescript, ...

Coffeescript Basic's

syntax und so.

  • Wer will eine langweilige Wikipedia-Einführung in Coffeescript hören?
  • Ich übersetze die folgenden Statements in Coffeescript
  • Im Anschluss erzähl ich vielleicht ein wenig Historie :)

live coding!!!

var \u1000 = '😻'; က
  • Editor:
    • output unten
    • erkennt ob javascript
    • wenn coffeescript, javascript rechts daneben
  • valides Javascript
  • \u1000 und က bedeuten identisches
  • Kein Semikolion
  • Kein var Statement
    • Coffeescript hat einen scope aware parser, anders als php, c, js, ...
    • Coffeescript erkennt, dass var noch nicht deklariert ist
  • Kein Mix aus Utf8 Zeichen, aus \u1000 -> က
  • Unterstes က entfernen, return value stimmt noch!
  • var davor schreiben, return value stimmt nicht mehr
  • alles ist eine Expression, alles gibt was zurück, alles!
  • Resultat:
    • foo = "bar"
if(0 === -0) { var a = 1; } a
  • 1. Übersetzen in Coffeescript
  • 2. was ist unnötig?
  • 1. Semikolon
  • 2. Klammern { und }
  • --- HEY wir haben Javascript!
  • 3. var
  • 4. Klammern ( und )
  • 5. doppelte gleichheitszeichen
  • 1. Coffeescript kennt keine schwachen vergleichsoperatoren
  • 2. a = 1 if `0 == -0` geht
  • 3. optional "is" möglich
  • if 0 == -0 a = 1
  • Oder: a = 1 if 0 is -0
  • Oder: 0 is -0 && a = 1
  • && entspricht and
  • ACHTUNG
    • if Statement gibt was zurück!
    • bei coffeescript gibt alles etwas zurück :)
THERE IS NO FUCKING MAGIC, REALLY THERE(IS(NO(FUCKING(MAGIC, REALLY)))) THERE IS ( NO ( FUCKING MAGIC, REALLY) )
  • 1. Funktionsaufrufe durch leerzeichen getrennt
  • 2. Syntax ist wenig überraschend
  • 3. Syntax lässt sich mischen, klammern sind optional
    • 1. Klammern müssen gesetzt werden wenns ohne doppeldeutig wäre
  • 4. Syntax ist sehr gnädig (letztes Beispiel)
  • 5. Warum alles groß geschrieben?
    • 1. there >>>"is"<<<<
(function() { return 5; })()
  • 1. Semikolon entfernen
  • 2. klammern weg
  • 3. function durch ->
  • 4. klammern hinzufügen, self call ...
  • 5. return weg
  • (-> 5)()
a = ->->->->->5 a()()()()()
  • Funktionen definieren
console.log "up" if console?.log
  • Existence operatoren
  • oder einfach nur console?.log?
  • oder einfach nur console?.log "up"
a = (cb) -> cb? "data"
  • schick schick für callbacks
x('._foo').html """ a href="#{getRouter().url 'user', user.id}"> img src="#{getUserImageService().getImage(user).getSrc()}"/> /a> """
  • 1. < am Anfang com HTML ricgtig setzen
  • 2. mehrere Zeilen
  • 3. Funktionen lassen sich embedden
document.a ?= c
  • Zuweisung falls kein wert vorhanden
function add(a, b) { return a + b; } add("Why am I a ", typeof + "");
  • Etwas komplizierteres beispiel
  • - was entfernen damit Syntaktisch noch korrekt?
  • - ;
  • - return
  • - function
  • - {
  • - (
  • + =
  • + ->
  • add = (a, b) -> a + b;
  • add "Why am I a ", typeof + ""
  • warum ists ne nummer?
    • +"" ist ne nummer :) (typeof(+""))
$(document).ready(function() { $("body").removeClass("noscript") });
  • Coffeescript wird 1 zu 1 zu Javascript.
  • Ihr könnt jederzeit das Coffeescript verwerfen.
  • Keine komplexen Proxies wie z.b. bei Dart / GWT nötig
  • Skript stimmt von trivago
    • jegliches Warum bitte an die frontend devs ...

The golden rule of CoffeeScript is:

"It's just JavaScript".

  • 1. wer Javascript kann, lernt CoffeeScript sehr schnell
  • 2. nur anderer Syntax
  • 2. maximal kompaktibel

The compiled output is readable and pretty-printed, ...

  • Ich mag keine Überraschungen
  • 1. CoffeeScript generiert was du erwartest, keine Überraschungen
  • 2. der Output ist lesbar, debugbar
  • 3. solltest du weg wollen von CoffeeScript, schnapp dir das JS...
    • 3.1 Der Weg zurück wird nie verbaut
    • 3.2 Anders als bei z.b. GWT

will work in every JavaScript runtime, ...

  • Ecmascript 5?
  • IE 6 ist kein Problem
  • kein problem auch optimiertes js zu embedden - solltet ihr was schnelleres finden ... :)

... and tends to run as fast or faster than the equivalent handwritten JavaScript.

  • Kein ASM.js
  • Glaubensfrage.
  • 1. Optimiert nicht auf den Browser
    • 1. GWT macht dies z.b.
  • 2. wollt ihr z.b. forEach, map o. etc. nutzen, tut es.

ASM.js for speed

GWT for nerds working @google

Dart for hipsters

JavaScript for runtime

CoffeeScript for humans (and PHP dev's :))

  • JS ist hölle für jede Runtime, nur google hat interesse dran ...
var someInt = 4; add = function(x, y) { return x + y; } add(someInt, add(someInt, 5));
  • just translate
  • kaskadierte funktion
  • auf die klammern achten
greeter = (name) -> "hello " + name x = (cb, arr) -> cb name for name in arr x(greeter, ["Andy", "Mario", "..."]).join ', '
  • 1. Code sieht komisch aus?
  • 2. Return Statement hinzufügen!
  • 3. wo ist der unterschied?
  • 4. letztes Statement wird returnt!
    • for hat eine return value!
    • ein array!
  • 5. wir sammeln alle rückgabewerte des Callbacks!
names = -> name for name in ["Andy", 'Maro', '...'] names().join ', '
  • Beispiel return Value der Collection von names.
$('meta') .toArray() .map((el) -> $(el).attr 'name') .filter((x) -> x && x.length) .reduce((a, b) -> a + ', ' + b)
  • Einfaches map and reduce Beispiel
  • underscore js ist auch von jeremy
  • funktional geht natürlich immer :)
$('some_selector').css({top: 42, left: 42})
  • Objektsyntax
  • .css top: 42, left: 42
  • oder
  • .css
    • top: 42
    • left: 42
  • korrigiert jegliche komma's
$.ajax url: url timeout: 5 data: form: "workspace" dataType: "jsonp" success: (data) => @setXData data
  • Wenn ihr es in { und } schreibt, dann geht auf "url" anstelle von url: url
x = (keyCode) -> switch keyCode when 38 command = "previous" when 40 command = "next" return command if command x 38
  • Switch hat einen Rückgabewert
x = (keyCode) -> switch keyCode when 38 then "previous" when 40 then "next" x 38
  • alternative Schreibweise um mit Switch zu arbeiten

CoffeeScript in the wild

  • ich hatte im vorfeld mal gefragt
  • 1. Praxisnahe Beispiele sollten es sein :)
$('#dialog').dialog()
  • wie man unten sieht, valides CoffeeScript
  • Eklig sowas,
  • Singleton, keine Architektur
  • - Just works -
  • nicht wartbar?
  • Wir sind Architekten :)
var a = (function() { function a() {} a.prototype.foo = function() { return "bar"; }; return a; })(); (new a).foo()
  • wer scheibt sowas in JavaScript?

a bit oop

  • wer schreibt oop JavaScript?
  • warum nicht?
  • oop ist performant!
class a foo: -> "bar" (new a).foo()
  • CoffeeScript kann klassen
  • Class.create war der grund für prototypeJS
  • wer findet rechts übersichtlicher?
    • wer von denen will mich nur ärgern?
class a constructor: -> @foo = foo; (new a "bar").foo
  • Konstruktor
  • parameter (@foo): ->
  • parameter mit default werten (@foo = "bar"): ->
class a setFoo: (@foo) -> @ getFoo: -> @foo (new a "bar").foo
  • typisches Beispiel für getter und setter
  • keine private variablen
    • Könnt natürlich drum rum bauen
class a constructor: (@foo = new ( class a: -> 5 )) -> (new a).foo.a()
  • 1. ein wenig vergewaltigt
  • 2. zeigt was möglich ist
  • 3. womöglich mitm servicelocator ganz interessant ^^
  • 4. parameterreihenfolge
class a @foo: -> "bar" a.foo()
  • Statische Funktionen
  • Statische Funktionen gibt es in JS nicht
    • werden kopiert beim extends
class a foo: -> "bar" class b extends a (new a).foo()
  • 1. klassische vererbung
  • 2. extends wird nur einmalig embedded
  • 3. performant, nur statische methoden werden kopiert
  • 4. klasse die extended wird muss vorhanden sein.
class a constructor: (@dom) -> @dom.find('.foo').click (e) -> @handelClickFoo e handelClickFoo: (e) -> 0
  • @entspricht this
  • 1. wo ist das Problem?
  • 2. => fat arrow
  • bei funktion
  • bei funktionsdeklaration

real world application

  • natürlich im kleinen
  • beispiele liegen der Präsentation bei
class main di: null getContainer: -> return @di if @di @di = new di @di.configure factories: dispatcher: (di)-> new dispatcher di controllerHello: (di) -> new controllerHello di.get('serviceGreeter') serviceGreeter: -> new serviceGreeter @di handle: (request) -> @getContainer().get('dispatcher')().dispatch request.controller (new main).handle controller: 'Hello'
  • werfen nur ein blick ins bootstrapping
  • getContainer und Handle sind teil des HttpKernelInterfaces

CoffeeScript

using php Storm.

  • 1. wer kennt phpstorm file watcher?
  • 2. wer nutzt diese?
  • Änderung einer Datei triggert ein Programm.
  • --bare
  • 1. Standadmäßig packt Coffeescript alles in eine anonyme funktion
  • Best Practice
  • Keine Probleme mit dem Scope
  • 1. Welche Probleme treten auf?
    • jede Datei liegt einzelnt da
    • .map wird nicht geinlinent
  • Chaos im Dateisystem
  • Abhängigkeit zu PHPStorm
  • Abhängigkeiten sind schlecht!
  • 1. wir wollen Continuous Integration!
  • 2. Continuous deployment
  • 3. Jemand Push't und die Magie nimmt ihren Lauf
  • 4. Lösung: Commandline!

CoffeeScript

using CoffeeScript.

  • CoffeeScript selbst ansehen
  • -c COMPILE!
  • -o DORECTORY!
clean:
	find . -iname "*.js" -exec rm {} \;
	find . -iname "*.map" -exec rm {} \;
	rm -rf build

js:
	coffee -bjc -o build/ \
	lib/di.coffee \
	lib/dispatcher.coffee \
	controller/abstract.coffee \
	controller/hello.coffee \
	service/greeter.coffee \
	main.coffee

run: clean js
	reset
	node build/.js
                    
...
make run
                    
...
node build/.js
YAAYYYY!!
hello!! folks
                    
  • 1. Wer schreibt Makefiles?
    • 1.1 Organisierte Bash Skripte
    • 1.2 ich mag sie :)
  • 2. rufen wir "make run" auf
  • 3. output des Skriptes.
  • 4. alle Sourcen sind im Repo!
  • -b bare, -j join, -c compile, -o out

Demo?

gut?

  • 1. Reihenfolge muss explizit angegeben werden
js:
	coffee -bjc -o build/ \
	lib/di.coffee \
	lib/dispatcher.coffee \
	controller/abstract.coffee \
	controller/hello.coffee \
	service/greeter.coffee \
	main.coffee
                    
  • 1. Reihenfolge muss explizit angegeben werden
  • Nutzt CommonJS
  • Standard für NodeJs Projekte
  • Können wir fürs web verwenden
  • identishcer Syntax wie nodejs
  • npm pakete nutzbar
  • viele Standard verfügbar, streams, buffer
  • Zum Bundeln nutzen wir Browserify
  • Quasi Standard
  • Kann Coffeescript
  • Auch ohne CoffeeScript geil
  • Alternative zu AMD, RequireJs
  • Alternative Loader, AMD, ..
_di = require './lib/di.coffee' _dispatcher = require './lib/dispatcher.coffee' _controllerLeft = require './controller/left.coffee' _controllerContent = require './controller/content.coffee' _controllerFooter = require './controller/footer.coffee' _serviceGreeter = require './service/greeter.coffee' class main di: null getContainer: -> return @di if @di @di = new _di @di.configure factories: dispatcher: (di)-> new _dispatcher di controllerLeft: (di) -> new _controllerLeft di.get('serviceGreeter') controllerContent: (di) -> new _controllerContent controllerFooter: (di) -> new _controllerFooter serviceGreeter: -> new _serviceGreeter @di handle: (request) -> @getContainer().get('dispatcher')().dispatchRoute request app = new main $('document').ready -> $('.app_controller').each (i, el) -> app.handle controller: $(el).data('controller') dom: $(el)

Demo?

  • im Browser
  • HTML Zeigen
    • 3 Controller
    • Alle werden dispatcht
  • SourceMaps
    • console.log zeigen
  • Debuggen von CoffeeScript
  • Gebundelt über Browserify via Grunt
  • Demo natürlich dabei!

mehr?

  • wir haben bereits...
  • via nodejs
  • via browserify im browser
  • was fehlt?
  • hacky
  • just for fun
  • Demo?
  • make all
  • main zeigen
  • browserify bundelt und embedded die require funktion
  • v8 implementiert nur eine funktion, erste zeile der main zeigen

Fragen?

thx.

@timglabisch

  • Würde mich über Feedback freuen.