YUI and Node.js
      Sitting in a tree
  S-E-R-V-I-N-G H-T-T-P



  Tom Hughes-Croucher
       @sh1mmer
YUI3 + Node.js
 IS SO AWESOME
    MY ENTIRE PRESENTATION IS IN
          COMIC SANS
AND YOU WILL STILL LOVE ME AT THE END
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
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
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
Summary
• YUI 3’s design made it easy to get
  running on Node.js

• JavaScript libraries are awesomely
  valuable on the server side

• Server side DOM shows crazy potential
  for a single code base
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/
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.

JavaScript Everywhere! Creating a 100% JavaScript web stack

  • 1.
    YUI and Node.js Sitting in a tree S-E-R-V-I-N-G H-T-T-P Tom Hughes-Croucher @sh1mmer
  • 2.
    YUI3 + Node.js IS SO AWESOME MY ENTIRE PRESENTATION IS IN COMIC SANS AND YOU WILL STILL LOVE ME AT THE END
  • 5.
    Node.js • Server-side JavaScriptprocess • Uses V8 • Non-blocking • Event Driven • CommonJS module format
  • 6.
    AW Node.js • ESServer-side JavaScript process OM • Uses V8 • Non-blocking • • Event Driven CommonJS module format E!
  • 7.
    At JSCONF.US 2010 Node was ⎻⎻⎻⎻⎻ this fast
  • 9.
    But Ryan doesn’t rolllike that. Ryan rolls like this
  • 11.
  • 12.
  • 13.
    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
  • 14.
    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.
  • 15.
    Progressive Enhancement is free* RememberWWCD (What Would Crockford Do) *close enough
  • 16.
    TL;DR: SSJS is Awesome Like a Unicorn riding a Narwhal
  • 18.
    YUI3 Awesome like aNarwhal riding a Unicorn
  • 19.
    YUI 3 • Modular •Sandboxed • Intrinsic component loading • Core team + community (50+ extensions) • Not just about manipulating the DOM
  • 20.
    YUI 3 • ScriptLoading • Remote i/o • Events and Attributes • Data Manipulation • Language Utilities • Templating
  • 22.
    Making it work- 1 YUI exports itself per the CommonJS spec if (typeof exports == 'object') { exports.YUI = YUI; }
  • 23.
    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); } });
  • 24.
  • 25.
    ‘ello World NodeStyle #!/usr/bin/env node var YUI = require("../lib/node-yui3").YUI, Y = YUI(); Y.log('ello World');
  • 26.
    ‘ello World YUIStyle #!/usr/bin/env node require("../lib/node-yui3").YUI().log('ello World');
  • 27.
    ‘ello World YUIStyle [~/examples (master)⚡] ➔ ./hello.js [INFO]: ello World
  • 28.
    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) { } }; });
  • 29.
    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'); });
  • 30.
    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...
  • 32.
    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)); }); });
  • 33.
    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- } } }
  • 34.
  • 35.
    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.
  • 36.
    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
  • 37.
    Rendering HTML - nodejs-dom • DOM element creation and manipulation • Selector API • YUI’s Node API
  • 38.
    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'); // ...
  • 39.
  • 40.
    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.
  • 41.
  • 42.
    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.
  • 43.
    Other Uses • Fastutility layer testing with YUI Test. • Smoke tests for DOM-centric code. • Could emulate some browser quirks. • Validation Code
  • 44.
    Summary • YUI 3’sdesign made it easy to get running on Node.js • JavaScript libraries are awesomely valuable on the server side • Server side DOM shows crazy potential for a single code base
  • 45.
    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/
  • 46.
    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.