CoffeeScript, An Introduction for Nodejs developers

49
| COFFEESCRIPT AN INTRODUCTION FOR NODE DEVELOPERS BY: MEHDI VALIKHANI SOFTWARE ENGINEER @ ALPHATISE Follow me: @mehdivk [email protected]

description

 

Transcript of CoffeeScript, An Introduction for Nodejs developers

Page 1: CoffeeScript, An Introduction for Nodejs developers

|

COFFEESCRIPTAN INTRODUCTION FOR NODE DEVELOPERS

BY: MEHDI VALIKHANISOFTWARE ENGINEER @ ALPHATISE

Follow me: @mehdivk [email protected]

Page 2: CoffeeScript, An Introduction for Nodejs developers

IT'S JUST JAVASCRIPTCOFFEESCRIPT IS A PROGRAMMING LANGUAGE THAT

TRANSCOMPILES TO JAVASCRIPT.

SYNTACTIC SUGAR TO JAVASCRIPT

Page 3: CoffeeScript, An Introduction for Nodejs developers

IT'S MATURE AND PRODUCTION-READY

DEVELOPED BY: JEREMY ASHKENAS

INITIAL COMMIT: DECEMBER 13TH, 2009FIRST RELEASE: DECEMBER 24H, 2009

VERSION 1.0: FEBRUARY 2010CURRENT VERSION: 1.8

Page 4: CoffeeScript, An Introduction for Nodejs developers

WHO'S USINGCOFFEESCRIPT?

DROPBOXGITHUB

Page 5: CoffeeScript, An Introduction for Nodejs developers

WRITE LESS, DO MOREHUMAN-READABLE CODE

STAY AWAY FROM WEIRD JS BEHAVIOUR

SAY GOODBYE TO PROTOTYPE! USE CLASSES

ANY MANY MORE ...

Page 6: CoffeeScript, An Introduction for Nodejs developers

COFFEESCRIPT SYNTAX

Page 7: CoffeeScript, An Introduction for Nodejs developers

NO MORE VAR ; ( )

async = require 'async' console.log async.VERSION

var async = require('async'); console.log(async.VERSION);

Page 8: CoffeeScript, An Introduction for Nodejs developers

FUNCTIONSIT'S PART OF OUR EVERYDAY LIFE IN JS WORLD

LET'S BE AGILE!

Page 9: CoffeeScript, An Introduction for Nodejs developers

addUser = (user, cb) -> model = new User #DO SOMETHING model.save (err, result) -> cb null, result

var addUser = function(user, cb) { var model = new User(); //DO SOMETHING model.save(function(err, result){ cb(err, result); }); }

Page 10: CoffeeScript, An Introduction for Nodejs developers

IMPLICIT RETURN

someFunction = (param1, param2) -> param1 * param2 * param2 console.log someFunction 100, 200

var someFunction; someFunction = function(param1, param2) { return param1 * param2 * param2; } console.log(someFunction(100, 200));

Page 11: CoffeeScript, An Introduction for Nodejs developers

OBJECTSGET RID OF THOSE { } ,

bus = routeNumber: 273 from: 'Wynyard' to: 'Chatswood' via: 'North Sydney, Pacific Highway'

var bus = { routerNumber: 273, from: 'Wynyad', to: 'Chatswood', via: 'North Sydney, Pacific Highway' }

Page 12: CoffeeScript, An Introduction for Nodejs developers

query = status: $in: ['active', 'pending_for_approval'] payment: $nin: ['invoice', 'free'] tc: $exists: true

var query = { status: { $in: ['active', 'pending_for_approval'] }, payment: { $nin: ['invoice', 'free'] }, tc: { $exists: true } }

Page 13: CoffeeScript, An Introduction for Nodejs developers

STRING INTERPOLOATION

meetup = 'Node' msg = "#{meetup} meeup is awsome!" console.log msg

var meetup = 'Node'; var msg = meetup + ' meetup is awsome!'; console.log(msg);

Page 14: CoffeeScript, An Introduction for Nodejs developers

CLASSESBETTER INHERITANCE WITHOUT PROTOTYPE

WE SHOULDN'T USE LIBRARIES TO HAVE CLASSES IN JS

Page 15: CoffeeScript, An Introduction for Nodejs developers

class Cache generateCacheKey: (key) -> throw new Error 'Not Implemented' getPeriod: -> 120 * 60 store: (key, data) -> throw new Error 'Not Implemented' clearCache: (key) -> #DO SOMETHING

class RedisCache extends Cache generateCacheKey: (key) -> "redis_cache_#{key}" store: (key, data) -> period = @.getPeriod() #STORE IN REDIS

Page 16: CoffeeScript, An Introduction for Nodejs developers

DESTRUCTURING OBJECTS

{Router} = require 'express' router = new Router

var express = require('express'); var Router = experss.Router; router = new Router();

Page 17: CoffeeScript, An Introduction for Nodejs developers

DESTRUCTURING ARRAYS

student = 'Mehdi Valikhani' [firstName, lastName] = student.split ' '

var student, ref, firstName, lastName; student = 'Mehdi Valikhani'; ref = student.split(' '); firstName = ref[0]; lastName = ref[1];

Page 18: CoffeeScript, An Introduction for Nodejs developers

DESTRUCTING ARGUMENTS

calculator = ({width, height}) -> width * height options = width: 10 height: 5 alert calculator options

Page 19: CoffeeScript, An Introduction for Nodejs developers

EXISTENTIAL OPERATOR ?REMOVE THOSE NULL OR UNDEFINED CHECKES FROM CODE

if err? #log to logger cb err

if (typeof err !== "undefined" && err !== null) //log to logger cb(err);

Page 20: CoffeeScript, An Introduction for Nodejs developers

INSTALL COFFEESCRIPTnpm install -g coffee-script

Page 21: CoffeeScript, An Introduction for Nodejs developers

EXECUTE A SCRIPTcoffee /path/to/script.coffee

Page 22: CoffeeScript, An Introduction for Nodejs developers

COMPILE A SCRIPTcoffee -c /path/to/script.coffee

Page 23: CoffeeScript, An Introduction for Nodejs developers

NODE + COFFEEFROM SCRATCH

REST API DEVELOPMENT USING EXPRESS + NODE + COFFEE

Page 24: CoffeeScript, An Introduction for Nodejs developers

CODE STRUCTURE

+ lib + books Book.coffee //Our Mongoose Model router.coffee //router for books API+ node_modules + body-parser //from JSON responses + coffee-script //compiler of Coffee files + express //express frameworkapp.coffee //express app configpackage.json // NO DESCRIPTIONindex.js //ACTUAL MAGIC HAPPENS HERE!

Page 25: CoffeeScript, An Introduction for Nodejs developers

app.coffee

bodyParser = require 'body-parser'express = require 'express'userRouter = require './lib/books/router'

app = express()app.use bodyParser.json()app.use '/users', userRouter

module.exports = app

Page 26: CoffeeScript, An Introduction for Nodejs developers

lib/books/router.coffee

{Router} = require 'express'Book = require './Book'router = new Router

fetchBook = (req, res, next) -> req.paramBook = Book next()

getBook = (req, res) -> res.json(req.paramBook)

router.route('/:book_id') .all(fetchBook) .get(getBook)

module.exports = router

Page 27: CoffeeScript, An Introduction for Nodejs developers

index.js

require('coffee-script/register'); var app = require('./app'); app.listen(1984, function(){ console.log('App is available via http://127.0.0.1:1984'); });

Page 28: CoffeeScript, An Introduction for Nodejs developers

RUN THE APPnode index.js

nodemon -e js,coffee index.js

Page 29: CoffeeScript, An Introduction for Nodejs developers

NODE + COFFEE

AN EXISTING PROJECT

Page 30: CoffeeScript, An Introduction for Nodejs developers

ADD FOLLOWING CODE TO YOUR STARTER FILErequire('coffee-script/regiter');

Page 31: CoffeeScript, An Introduction for Nodejs developers

THAT'S IT!Add .coffee files, write your code in coffeerequire other .js or .coffee files as always

Page 32: CoffeeScript, An Introduction for Nodejs developers

RUN THE APPnode index.js

nodemon -e js,coffee index.js

Page 33: CoffeeScript, An Introduction for Nodejs developers

DEBUGGINGCOFFEESCRIPTAPPLICATIONS

Page 34: CoffeeScript, An Introduction for Nodejs developers

USE "DEBUGGER" AS ALWAYS

fetchBook = (req, res, next) -> debugger req.paramBook = Book next()

node debug index.js

Page 35: CoffeeScript, An Introduction for Nodejs developers

BUT DON'T FORGET!in debug mode, you will be faced with compiled

JS code

break in lib/books/router.coffee:11 9 10 fetchBook = function(req, res, next) { 11 debugger; 12 req.paramBook = Book; 13 return next(); debug> repl Press Ctrl + C to leave debug repl > req.params.book_id '123' >

Page 36: CoffeeScript, An Introduction for Nodejs developers

JAVASCRIPT SCOPINGin JavaScript, the scope of a variable is

defined by its location within the source code(it is apparent lexically) and nested

functions have access to variables declared intheir outer scope. - mozilla.org

Page 37: CoffeeScript, An Introduction for Nodejs developers

Question: What's result of running this code?

name = 'Alex'

greeting = -> name = 'James' console.log "Hey #{name}!"

greeting() console.log "Hey #{name}!"

Page 38: CoffeeScript, An Introduction for Nodejs developers

A:> Hey James!> Hey James!

B:> Hey James!> Hey Alex!

Page 39: CoffeeScript, An Introduction for Nodejs developers

"A" IS CORRECT ANSWER> Hey James!> Hey James!

Page 40: CoffeeScript, An Introduction for Nodejs developers

THIS IS COMPILED-TO-JS VERSION OF ABOVECODE

var greeting, name;

name = 'Alex';

greeting = function() { name = 'James'; return console.log("Hey " + name + "!");};

greeting();

console.log("Hey " + name + "!");

Page 41: CoffeeScript, An Introduction for Nodejs developers

TWO IMPORTANT FACTS ABOUT COFEESCRIPT SCOPING

Variable shadowing is not allowed

variable is created at the moment of the first assignment to it

Page 42: CoffeeScript, An Introduction for Nodejs developers

"VARIABLE SHADOWING IS NOT ALLOWED"

DOESN'T MEAN

YOU CAN'T DEFINE A VARIABLE MORE THANONCE IN DIFFERENT FILES

IT MEANS

YOU CAN'T DEFINE IT MORE THAN ONCE IN ASINGLE FILE

Page 43: CoffeeScript, An Introduction for Nodejs developers

SO WHAT SHOULD I DO IF I WANT TO HAVESHADOWS?

It's not a good practice, don't do that!

It decreases readbility of your code!

Brings more confusion to your code

With shadowing you can't access our variables anymore (withsame name)

Page 44: CoffeeScript, An Introduction for Nodejs developers

USE `` TO BRING VAR BACK

name = 'Alex'

greeting = -> ̀ ` name = 'James' console.log "Hey #{name}!"

greeting() console.log "Hey #{name}!"

var name

It a kind of hack! Don't do that!

Page 45: CoffeeScript, An Introduction for Nodejs developers

SHADOW IT USING FUNCTION PARAMETER

name = 'Alex'

greeting = (name = '')-> name = 'James' console.log "Hey #{name}!"

greeting() console.log "Hey #{name}!"

Better first solution!

Page 46: CoffeeScript, An Introduction for Nodejs developers

USE COFEESCRIPT'S CLOSURE FEATUREThis is much much better!

name = 'Alex'

greeting = -> do (name = '') -> name = 'James' console.log "Hey #{name}!"

greeting() console.log "Hey #{name}!"

Page 47: CoffeeScript, An Introduction for Nodejs developers

MORE INFO ABOUT LEXICAL SCOPING:

https://github.com/raganwald-deprecated/homoiconic/blob/master/2012/09/actually-YOU-dont-understand-lexical-scope.md

https://github.com/raganwald-deprecated/homoiconic/blob/master/2012/09/lexical-scope-in-coffeescript.md

Page 48: CoffeeScript, An Introduction for Nodejs developers

USEFUL RESOURCESYour best friend

Don't translate CoffeeScript to JS, try to learn as new langage

Teaches CoffeeScript as new language instrad of translating toJS

Best Practices

CoffeeScript Docs

CoffeeConsole: A Google Chrome Extention

CoffeeScript Ristretto

The Little Book On CoffeeScript

CoffeeScript Style Guide

Page 49: CoffeeScript, An Introduction for Nodejs developers

Thank you!