Who am i?
- JavaScript Engineer
- Works for appendTo
- tysoncadenhead.com
My Office
Compound.JS
An explosive MVC Framework for NodeJS
What is compoundJS?
- MVC framework for NodeJS
- Allows you to build a web application in minutes
- compoundjs.com
What?
What is NodeJS?
- JavaScript on the server-side
- Really fast
- The best thing since sliced bread
- nodejs.org
What is Express?
- Web application framework for Node
- Provides an interface for requests and routing
- Non-opinionated
-
expressjs.com
var express = require('express'),
app = express();
app.get('/hello.txt', function(req, res){
res.send('Hello World');
});
app.listen(3000);
If Express is so great,
why do we need Compound?

MVC

Other Goodies

- Scaffolding
- JugglingDB
- Models
- Easy routing
- View Helpers
Now can talk we
about CompoundJS?
Generators
Using the Compound scaffolding
Generate an application
compound init myApp && cd myApp
npm install
compound generate app myApp
Generate CRUD functionality
compound generate crud user name bio age:number createdAt:date
Running the application
Start the server
compound server 3000
Controllers
Using Compound routing
exports.routes = function (map) {
// Maps CRUD methods map.resources('users');
// Maps a custom method map.get('users/login', 'users#login');
// Maps the homepage map.root('users#dashboard'); map.all(':controller/:action'); map.all(':controller/:action/:id'); };
The anatomy of a controller
load('application');
before(function () {
// ...
}, {
only: ['edit']
});
action('login', function () {
render();
});
action(function edit() {
//...
});
send()
Status code
action('destroy', function () {
send(403); // Forbidden
});
Json
action('find', function () {
send({
name: 'Darth Vader',
age: 45
});
});
Flash Messages
In the controller
action(function create() {
flash('info', 'User created');
redirect(path_to.users);
});
In the view
<% var flash = request.flash('info').pop(); if (flash) { %>
<div class="alert alert-info">
<a class="close" data-dismiss="alert">×</a>
<%- flash %>
</div>
<% } %>
Views
What view renderers are supported in Compound?
- EJS
- Jade
- Anything Express Supports
How do they work?
- When the controller calls render();
- this in the controller gets passed in
Render a different view
render('viewName');
Pass data in directly
render(undefined, { name: 'Darth Vader' });
Partials
Easily share code snippets between views<%- include _form %>
Layouts
- Stored in views/layouts
- Defaults to [controller]_layout.[ext]
- Falls back on application_layout.[ext]
<html>
<head>
<title><%= title %></title> <%- stylesheet_link_tag('bootstrap') %> <%- javascript_include_tag('application') %>
</head>
<body>
<%- body %>
</body>
</html>
Juggling DB

What Does it do?
- DataBase abstraction
- Easily switch out database types
- Common API for database interactions
- Has tons of database adapters
- MySQL
- Redis
- MongoDB
- CouchDB
- SQL Lite
- ...
What it looks like
Defining a database schema:
User = schema.define('User', {
name: String,
bio: Text,
approved: Boolean,
joinedAt: Date,
age: Number
});
Post = schema.define('Post', {
title: { type: String, length: 255 },
content: { type: Text },
date: { type: Date, default: Date.now },
published: { type: Boolean, default: false }
});
Creating Data
User.create({
name: 'Anakin Skywalker',
bio: 'Jedi and pilot',
approved: false,
joinedAt: new Date(),
age: 12
}, function (err, user) {
console.log(user);
});
Retrieving data
Get everybody
User.all(function (err, users) {
console.log(users); // Array
});
Get a few certain people
User.all({
where: { age: 12 }
}, function (err, users) {
console.log(users); // Array
});
Get someone special
var id = 1;
User.find(id, function (err, user) {
console.log(user); // Array
});
Updating Data
var id = 1;
User.find(id, function (err, user) {
user.updateAttributes({
name: 'Darth Vader',
bio: 'Dark Lord of the Sith',
approved: true,
age: 45
}, function (err, user) {
console.log(user);
});
});
Deleting Data
var id = 1;
User.find(id, function (err, user) {
user.destroy(function (err) {
console.log('BOOM!');
});
});
Compound Models
module.exports = function (compound, User) {
User.splitName = function () {
return this.name.split(' ');
};
User.hasMany(Post, {
as: 'posts',
foreignKey: 'userId'
});
User.belongsTo(Affiliation, {
as: 'affiliation',
foreignKey: 'affiliationId'
});
};
Validation
User.validatesPresenceOf('bio', 'name');
User.validatesLengthOf('name', { min: 3 });
Built in validation
- presence
- length
- format
- numericality
- inclusion
- exclusion
Custom Validation
User.validate('validateType', function (err) {
if (this.type === 'Droid') {
err();
}
}, {
message: 'We don\'t serve their kind here!'
});
Testing

Why do tests matter?
- They stop us from releasing bugs
- Sanity check
- Help us to determine when
apps are ready to release
How do tests work in Compound?
How to write Unit
tests for Compound
function ValidAttributes () {
return {
name: 'Boba Fett',
age: 1
};
}
exports['models controller'] = {
'POST create': function (test) {
var model = new ValidAttributes;
var create = Model.create;
Model.create = sinon.spy(function (data, callback) {
test.strictEqual(data, model);
callback(null, model);
});
test.post('/models', {Model: model}, function () {
test.redirect('/models');
test.flash('info');
test.done();
});
},
...
};
Other cool things

Compound on the client-side
- New functionality
- Use controllers and routers on client-side
- JugglingDB on client-side too
-
https://github.com/compoundjs/client-side
Asset compiler
Included compilers:
- CoffeeScript
- Less
- Stylus
- SASS
app.configure(function(){
app.use(compound.assetsCompiler.init());
app.set('cssEngine', 'sass');
});
Compound tools
Run compound commands from the terminalcompound.tools.starwars = function () { switch (compound.args.shift()) { case 'episode4':
break; case 'episode5':
console.log('The Empire Strikes Back'); break; }; }
In the terminal
compound starwars episode5
Questions?

compoundjs
By tysoncadenhead
compoundjs
- 4,563