Server Side JavaScript - You ain't seen nothing yet
-
Upload
tom-hughes-croucher -
Category
Technology
-
view
7.654 -
download
1
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
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 wasBrought to you by
the letters:J and S
And the fonts:Comic Sansmonofur
Tom Hughes-Croucher@sh1mmer
Slides, etc --> http://speakerrate.com/sh1mmer
Pls rate me. kthxbai.