Server Side JavaScript - You ain't seen nothing yet

Post on 12-May-2015

7.654 views 1 download

Tags:

Transcript of Server Side JavaScript - You ain't seen nothing yet

Server Side JavaScriptYou ain’t seen nothing yet

Tom Hughes-Croucher @sh1mmer

Server Side Javascript IS SO AWESOMEMY ENTIRE PRESENTATION IS IN

COMIC SANS AND YOU WILL STILL LOVE ME AT THE END

Why SSJS?

JavaScript programmers

3 > 2 > 1

Massive Code base of YUI and other JS librariesI heard some people use this thing called jQuery,

but I’m not convinced it’ll catch on

Laziness or “I’m sick of writing stuff twice”I could have said efficiency, but I think we all secretly long to sit around in our y-fronts. Except Higgins, who already does.

Progressive Enhancement is free*Remember WWCD (What Would Crockford Do)

*close enough

TL;DR:SSJS is Awesome

Like a Unicorn riding a Narwhal

Why now?

1. Professionalism

“Yahoo!'s corporate motto is: Don't be

eval().“

“Doug Crockford's JavaScript is so strict, that uncaught

exceptions would trigger global thermonuclear war“

2. JavaScript Runtimes

Runtimes

• V8 (Google), C++

• Spider Monkey (Mozilla), C++

• Rhino (Mozilla), Java

JavaScript Performance

V8

Spider Monkey

An Overview of SSJS

!

Runtime != Browser

No DOM for you!

JavaScript on Server• Rhino

• JavaScript 1.7

• SpiderMonkey

• JavaScript 1.8

• V8

• ECMAScript 3

Huh?

JavaScript is

• Proprietary to Netscape (now Mozilla)

• “Ahead” of ECMAScript

• Only really deployed in Mozilla projects

• Only useful on the server

ECMAScript is• A standard

• Implemented in all browsers

• ECMAScript-262 3rd ed. ~ JavaScript 1.5

• ECMAScript-262 5th ed. has no JavaScript equivalent

JavaScript 1.6+

• E4X (EcmaScript For XML)

• Let scope blocks

• Generators

• Generator expressions

Frameworks

CommonJS

CommonJS• Set of standards for SSJS

• Modules

• File System

• etc

• Cross-implementation API

• Still implementation specific code

Application Frameworks

Narwhal

Most Complete Implementation of

CommonJS

Works on lots of run-times

JACK/JSGI

JSGI Middleware

function(env) {

return { status : 200, headers : {"Content-Type":"text/plain"}, body : ["Hello world!"] };}

JSGI Middleware

function Head(app) { return function(env) { var result = app(env); if (env["REQUEST_METHOD"] === "HEAD") result.body = []; return result; }}

Fab

Fab

Fab

Fab

Fab• with ( fab = require( "../" ) ) module.exports = fab  ( contentLength )  ( stringify )   ( /\/date/ )    ( tmpl )      ( "The date is <%= this.toDateString() %>." )    ()  ( /\/time/ )    ( tmpl )      ( "The time is <%= this.toTimeString() %>." )    ()  ( new Date );

Node.js• Server-side JavaScript process

• Uses V8

• Non-blocking

• Event Driven

• CommonJS module format

Node.js• Server-side JavaScript process

• Uses V8

• Non-blocking

• Event Driven

• CommonJS module format

AWESOME!

At JSCONF.US 2010Node was ☜⎻⎻⎻⎻⎻☞ this fast

ButRyan doesn’t roll like that. Ryan rolls like this

Community, much?

Node.js + YUI3 =Awesome

like a Narwhal riding a Unicorn

YUI 3• Modular

• Sandboxed

• Intrinsic component loading

• Core team + community (50+ extensions)

• Not just about manipulating the DOM

YUI 3• Script Loading

• Remote i/o

• Events and Attributes

• Data Manipulation

• Language Utilities

• Templating

Making it work - 1

if (typeof exports == 'object') { exports.YUI = YUI; }

YUI exports itself per the CommonJS spec

Making it work - 2

YUI({ logFn: function(str, t, m) { if (str instanceof Object || str instanceof Array) { if (str.toString) { str = str.toString(); } else { str = sys.inspect(str); } } // output log messages to stderr sys.error('[' + t.toUpperCase() + ']: ' + m + str); }});

Fin.

‘ello World Node Style

#!/usr/bin/env nodevar YUI = require("../lib/node-yui3").YUI, Y = YUI();

Y.log('ello World');

‘ello World YUI Style

#!/usr/bin/env noderequire("../lib/node-yui3").YUI().log('ello World');

[~/examples (master)⚡] ➔ ./hello.js [INFO]: ello World

‘ello World YUI Style

Enabling YUI’s LoaderYUI.add(‘get’, function(Y) { // reads from file system or creates a httpClient // for remote data. Y.Get.script = function(s, cb) { var urls = Y.Array(s), url, i, l = urls.length; for (i=0; i<l; i++) { // doesn't need to be blocking, so don't block. YUI.include(url, function(err) { if (err) { Y.log(err, 'error', 'get'); } pass(cb); }); // replaced with process.compile so YUI doesn’t // need to be global // require.async(url, function (err, mod) { } };});

Enabling YUI’s Loader#!/usr/bin/env nodevar YUI = require('../lib/node-yui3').YUI;

YUI({ filter: 'debug'}).use('event-custom', function(Y) { Y.on('pwnd', function() { Y.log('Never gonna give you up, never gonna let you down...'); });

Y.fire('pwnd');});

Enabling YUI’s Loader[~/examples (master)⚡] ➔ ./loader.js [INFO]: (yui) Module requirements: event-custom[INFO]: (yui) Modules missing: event-custom, 1[INFO]: (yui) Fetching loader: yui_3_1_0_1_12711895820541, ./yui3/build/loader/loader-debug.js[INFO]: (get) URL: /lib/yui3/build/loader/loader-debug.js[INFO]: (yui) Module requirements: yui-base,yui-log,dump,oop,yui-later,event-custom[INFO]: (yui) Modules missing: dump,oop,event-custom, 3[INFO]: (yui) Using Loader[INFO]: (loader) attempting to load dump, ./yui3/build/[INFO]: (get) URL: /lib/yui3/build/dump/dump-debug.js[INFO]: (loader) attempting to load oop, ./yui3/build/[INFO]: (get) URL: /lib/yui3/build/oop/oop-debug.js[INFO]: (loader) attempting to load event-custom, ./yui3/build/[INFO]: (get) URL: /lib/yui3/build/event-custom/event-custom-debug.js[INFO]: (loader) loader finishing: success, yui_3_1_0_1_12711895820541, yui-base,yui-log,dump,oop,yui-later,event-custom[INFO]: (event) yui_3_1_0_1_12711895820544: pwnd->sub: yui_3_1_0_1_12711895820545[INFO]: Never gonna give you up, never gonna let you down...

Accessing Remote Data

#!/usr/bin/env node

var sys = require('sys'), YUI = require('../lib/node-yui3').YUI;

YUI().use('json', 'gallery-yql', function(Y) { var q = 'select * from github.user.info where (id = "apm")', o = new Y.yql(q); o.on('query', function(r) { //sys.inspects serializes objects to text sys.puts(sys.inspect(r)); });});

Using the YQL module from YUI Gallery

Accessing Remote Data[~/src/nodejs-yui3/examples (master)⚡] ➔ ./yql.js [INFO]: (get) URL: http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20github.user.info%20where%20(id%20%3D%20%22apm%22)&format=json&callback=YUI.yql.yui_3_1_0_1_12711910026086&env=http%3A%2F%2Fdatatables.org%2Falltables.env&

{ count: '1', created: '2010-04-13T08:36:47Z', lang: 'en-US', results: { user: { 'gravatar-id': 'fd657f26f290d8869901f0eaf3441b97' , name: 'Adam Moore' , login: 'apm' // -snip- } }}

DOMIt’s BOM.

What about the DOM?• YUI isn’t all about the DOM

• But YUI has many DOM-centric modules.

• Being able to use these components on the server opens up some interesting opportunities.

Rendering HTML - nodejs-dom

• Dav pulled together two open source projects to do it:

• jsdom - DOM level 1 support, written in JavaScript

• node-htmlparser - HTML parser written in JavaScript. Needed for innerHTML

• These are not nodeJS specific implementations

Rendering HTML - nodejs-dom

• DOM element creation and manipulation

• Selector API

• YUI’s Node API

Rendering HTML - nodejs-dom

#!/usr/bin/env nodevar sys = require('sys'), http = require('http'), url = require('url');var YUI = require("../lib/node-yui3").YUI;YUI().use('nodejs-dom', 'node', function(Y) { var document = Y.Browser.document, navigator = Y.Browser.navigator, window = Y.Browser.window; http.createServer(function (req, res) { var urlInfo = url.parse(req.url, true); YUI().use('nodejs-dom', 'node', function(Page) { document = Page.Browser.document; navigator = Page.Browser.navigator; window = Page.Browser.window; document.title = 'Calendar Test'; Page.one('body').addClass('yui-skin-sam'); var ln = document.createElement('link'); // ...

Rendering HTML

http://yuiloader.davglass.com/calendar/

Progressive Enhancement

• YUI 2 calendar control is loaded via the YUI 2 in 3 project

• The calendar control is fully rendered on the server.

• No script.

• Page and nav clicks are round trips.

• If script is enabled, we could enhance the links to pull only the data for each page and render on the client.

Multiple Response Types

http://yuiloader.davglass.com/template/

Multiple Response Types• First response will render the entire page.

• A client without script can request the fully rendered page.

• A script enabled client can request just the new content.

• A script enabled client with the source that is running on the server can request just the JSON data structure that creates the content.

• It’s the same code.

Other Uses

• Fast utility layer testing with YUI Test.

• Smoke tests for DOM-centric code.

• Could emulate some browser quirks.

• Validation Code

Summary• SSJS is awesome because

• We are JavaScript programmers

• Reuse (libraries/code)

• Progressive Enhancement

• Node.js + YUI3 rocks

• YUI 3’s was easy to get running on Node.js

• Server side DOM allows for a single code base

Today presentation wasBrought to you by

the letters:J and S

And the fonts:Comic Sansmonofur

Tom Hughes-Croucher@sh1mmer

croucher@yahoo-inc.com

Slides, etc --> http://speakerrate.com/sh1mmer

Pls rate me. kthxbai.