Server Side
         JavaScript
          You ain’t seen nothing yet




Tom Hughes-Croucher                    @sh1mmer
Server Side Javascript
  IS SO AWESOME
    MY 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 libraries
  I 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
V8




                    Spider
                    Monkey

JavaScript Performance
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
Framew
      orks
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
AW Node.js
•
  ESServer-side JavaScript process



      OM
•   Uses V8

•   Non-blocking

•
•
    Event Driven
    CommonJS module format   E!
At JSCONF.US 2010
   Node was   ⎻⎻⎻⎻⎻   this fast
But
Ryan 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
YUI exports itself per the CommonJS spec


  if (typeof exports == 'object') {
      exports.YUI = YUI;
  }
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 node
var YUI = require("../lib/node-yui3").YUI,
    Y = YUI();

Y.log('ello World');
‘ello World YUI Style

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

[~/examples (master)⚡] ➔ ./hello.js
[INFO]: ello World
Enabling YUI’s Loader
YUI.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 node
var 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
  Using the YQL module from YUI Gallery
#!/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));
     });
});
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=ht
tp%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-
        }
     }
}
DOM
It’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 node
var 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
Resources
•   YUI: http://developer.yahoo.com/yui/

•   Node.js: http://nodejs.org/

•   nodejs-yui: http://github.com/davglass/nodejs-
    yui3/

•   nodejs-yui3loader: http://github.com/davglass/
    nodejs-yui3loader

•   Test Loader: http://yuiloader.davglass.com/demo/

•   http://yuiloader.davglass.com/calendar/
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 was
 Brought to you by         And the fonts:
    the letters:            Comic Sans
      J and S                monofur

 Tom Hughes-Croucher       Slides, etc --> http://
      @sh1mmer           speakerrate.com/sh1mmer
croucher@yahoo-inc.com      Pls rate me. kthxbai.

Server Side JavaScript - You ain't seen nothing yet

  • 1.
    Server Side JavaScript You ain’t seen nothing yet Tom Hughes-Croucher @sh1mmer
  • 2.
    Server Side Javascript IS SO AWESOME MY ENTIRE PRESENTATION IS IN COMIC SANS AND YOU WILL STILL LOVE ME AT THE END
  • 3.
  • 4.
  • 5.
    Massive Code baseof YUI and other JS libraries I heard some people use this thing called jQuery, but I’m not convinced it’ll catch on
  • 6.
    Laziness or “I’msick 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.
  • 7.
    Progressive Enhancement is free* RememberWWCD (What Would Crockford Do) *close enough
  • 8.
    TL;DR: SSJS is Awesome Like a Unicorn riding a Narwhal
  • 10.
  • 11.
  • 13.
    “Yahoo!'s corporate mottois: Don't be eval().“
  • 14.
    “Doug Crockford's JavaScriptis so strict, that uncaught exceptions would trigger global thermonuclear war“
  • 15.
  • 16.
    Runtimes • V8 (Google),C++ • Spider Monkey (Mozilla), C++ • Rhino (Mozilla), Java
  • 17.
    V8 Spider Monkey JavaScript Performance
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
    JavaScript on Server •Rhino • JavaScript 1.7 • SpiderMonkey • JavaScript 1.8 • V8 • ECMAScript 3
  • 23.
  • 24.
    JavaScript is • Proprietaryto Netscape (now Mozilla) • “Ahead” of ECMAScript • Only really deployed in Mozilla projects • Only useful on the server
  • 25.
    ECMAScript is • Astandard • Implemented in all browsers • ECMAScript-262 3rd ed. ~ JavaScript 1.5 • ECMAScript-262 5th ed. has no JavaScript equivalent
  • 26.
    JavaScript 1.6+ • E4X(EcmaScript For XML) • Let scope blocks • Generators • Generator expressions
  • 28.
    Framew orks
  • 29.
  • 30.
    CommonJS • Set ofstandards for SSJS • Modules • File System • etc • Cross-implementation API • Still implementation specific code
  • 32.
  • 33.
  • 34.
  • 35.
    Works on lotsof run-times
  • 36.
  • 37.
    JSGI Middleware function(env) { return { status : 200, headers : {"Content-Type":"text/plain"}, body : ["Hello world!"] }; }
  • 38.
    JSGI Middleware function Head(app) { return function(env) { var result = app(env); if (env["REQUEST_METHOD"] === "HEAD") result.body = []; return result; } }
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
    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 );
  • 47.
    Node.js • Server-side JavaScriptprocess • Uses V8 • Non-blocking • Event Driven • CommonJS module format
  • 48.
    AW Node.js • ESServer-side JavaScript process OM • Uses V8 • Non-blocking • • Event Driven CommonJS module format E!
  • 49.
    At JSCONF.US 2010 Node was ⎻⎻⎻⎻⎻ this fast
  • 51.
    But Ryan doesn’t rolllike that. Ryan rolls like this
  • 53.
  • 64.
    Node.js + YUI3= Awesome like a Narwhal riding a Unicorn
  • 66.
    YUI 3 • Modular •Sandboxed • Intrinsic component loading • Core team + community (50+ extensions) • Not just about manipulating the DOM
  • 67.
    YUI 3 • ScriptLoading • Remote i/o • Events and Attributes • Data Manipulation • Language Utilities • Templating
  • 68.
    Making it work- 1 YUI exports itself per the CommonJS spec if (typeof exports == 'object') { exports.YUI = YUI; }
  • 69.
    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); } });
  • 70.
  • 71.
    ‘ello World NodeStyle #!/usr/bin/env node var YUI = require("../lib/node-yui3").YUI, Y = YUI(); Y.log('ello World');
  • 72.
    ‘ello World YUIStyle #!/usr/bin/env node require("../lib/node-yui3").YUI().log('ello World');
  • 73.
    ‘ello World YUIStyle [~/examples (master)⚡] ➔ ./hello.js [INFO]: ello World
  • 74.
    Enabling YUI’s Loader YUI.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) { } }; });
  • 75.
    Enabling YUI’s Loader #!/usr/bin/envnode var 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'); });
  • 76.
    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...
  • 77.
    Accessing Remote Data Using the YQL module from YUI Gallery #!/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)); }); });
  • 78.
    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=ht tp%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- } } }
  • 79.
  • 80.
    What about theDOM? • 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.
  • 81.
    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
  • 82.
    Rendering HTML - nodejs-dom • DOM element creation and manipulation • Selector API • YUI’s Node API
  • 83.
    Rendering HTML - nodejs-dom #!/usr/bin/env node var 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'); // ...
  • 84.
  • 85.
    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.
  • 86.
  • 87.
    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.
  • 88.
    Other Uses • Fastutility layer testing with YUI Test. • Smoke tests for DOM-centric code. • Could emulate some browser quirks. • Validation Code
  • 89.
    Resources • YUI: http://developer.yahoo.com/yui/ • Node.js: http://nodejs.org/ • nodejs-yui: http://github.com/davglass/nodejs- yui3/ • nodejs-yui3loader: http://github.com/davglass/ nodejs-yui3loader • Test Loader: http://yuiloader.davglass.com/demo/ • http://yuiloader.davglass.com/calendar/
  • 90.
    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
  • 91.
    Today presentation was Brought to you by And the fonts: the letters: Comic Sans J and S monofur Tom Hughes-Croucher Slides, etc --> http:// @sh1mmer speakerrate.com/sh1mmer croucher@yahoo-inc.com Pls rate me. kthxbai.