Download - KrakenJS
Tim Messerschmidt @SeraAndroid LondonJS Conf 2014
A story of!technical debt
Application stacks at PayPal
C++ Java
Environments & Lean UX
Prototyping Production
Application stacks at PayPal
C++ XSL
Java JSP
Node JS
Node & JS at PayPal Moving away from Java architecture • CSS, HTML and even JS in Java • Originally replaced by JSP
Rapid development & deployment cycles • Open Source Stack • Bootstrap for frontend • JavaScript templating via Dust • V8 in PayPal’s C++ stack for legacy app UI
New stack at PayPal
C++ Java Node
Dust
Advantages of Node Results of using Node at PayPal • Teams between 1/3 to 1/10 of Java teams • Doubled requests per second • 35% decrease in average response time • Lines of code shrunk by factor 3 to 5 • Development twice as fast • JS both on frontend and backend
Release the!Kraken!
What is Kraken? A JS suite on top of Node.js and Express Preconfigured with different best practices and tools:
• Dust for templates • LESS as CSS preprocessor • RequireJS as JS file and module loader • Grunt for running tasks • Runtime updates for UI code
But why?!
Project structure Opinionated about separation of logic and presentation
• /config • /controllers • /models • /public/templates • /locales • /tests
Lusca
Kappa Adaro
Makara
… and many more
Makara Local content bundles Internationalization support for Node apps var i18n = require('makara');var provider = i18n.create(config);provider.getBundle('index', 'en_US', function (err, bundle) { var string = bundle.get('key');});
Property files for Makara index.title=KrakenJS at LondonJS Confindex.speaker=Tim Messerschmidtindex.greeting=Ahoi {attendeeName}!# A listindex.speakers[0]=Lea Verouindex.speakers[1]=Peter-Paul KochIndex.speakers[2]=Hannah Wolfe# A mapindex.sponsors[PP]=PayPalindex.sponsors[GH]=GitHub# And subkeysindex.conference.language=JS
Makara in use Defining multiple values /locales/US/en/index.properties• index.greeting=Hello {name}!
/locales/ES/es/index.properties• index.greeting=Hola {name}!
Accessing keys in templates <h1>{@pre type="content" key="index.greeting"/}</h1>
Lusca Security settings against various vulnerabilities
Cross-site request forgery support Clickjacking / X-Frame-Options Output escaping against XSS via Dust Content Security Policy
Lusca configuration Configuration in middleware.json
"appsec": {"csrf": true,"csp": false,"p3p": false,"xframe": "SAMEORIGIN”
}
… or using Lusca’s methods
Lusca against CSRF A token is added to the session automatically
var express = require('express'),appsec = require('lusca'),server = express();
server.use(appsec.csrf());
The template needs to return the token:
<input type="hidden" name="_csrf" value="{_csrf}”>
Adaro Brings Dust as default templating engine Designed to work together with Makara
dustjs.onLoad = function (name, context, callback) {// Custom file read/processing piplinecallback(err, str);
}app.engine('dust', dustjs.dust({ cache: false }));app.set('view engine', 'dust');
Templating with Dust Layout
<html> <body> {>"{_main}"/} </body></html>
Content page as partial
<div>Hello!</div>dust.render(’partial', { layout: ’template' }, ...);
Templating with Dust Sections
{#modules} {name}, {description}{~n}{/modules}
View context
{ modules: [ { name: “Makara”, description: “i18n” }, { name: “Lusca”, description: “security settings” }]
}
Templating with Dust Conditionals
{#modules}{name}, {description}{~n}
{:else}No modules supported :(
{/modules}{?modules}
modules exists!{/modules}{^modules}
No modules!{/modules}
Kappa Serves as NPM Proxy Enables support for private npm repos Based on npm-delegate hapi support Global or local installation
npm install -g kappakappa -c config.json
Configuring Kraken Lives in /config/app.json
Development vs. Production environments • 2nd configuration allowed:
– app-development.json
• Usage of NODE_ENV for environment
nconf for credentials and other variables
The Generator
Getting started sudo npm install -g generator-krakenyo kraken ,'""`. / _ _ \ |(@)(@)| Release the Kraken! ) __ ( /,'))((`.\ (( (( )) )) `\ `)(' /'
Generation yo kraken:controller myControllerRespond to XHR requests? (Y/n)create controllers/myController.jscreate test/myController.js
Result without XHR var myModel = require('../models/model');module.exports = function (app) {var model = new myModel();
app.get(’/ahoi', function (req, res) { res.render(’ahoi', model);});
};
Result with XHR app.get('/ahoiXHR', function (req, res) {res.format({ json: function () { res.json(model); }, html: function () { res.render(’ahoiXHR', model); }});
});
Models yo kraken:model unicorncreate models/unicorn.jsmodule.exports = function UnicornModel() {return { name: ‘Charlie’};
};
Summary
Thanks! Tim Messerschmidt @SeraAndroid [email protected] slideshare.com/paypal