Tesla - a powerful web framework for Node.js

Tesla.js

Tesla is a modern MVC style framework built on to of Node.js and Express. It's build to be fast, simple & easy to configure, with sane defaults and flexible boilerplates to get you up and running as quickly as possible.

back to top

Features

MVC

Simple but useful MVC structure with optional scaffolding to auto-create models, controllers & even a simple JSON API for you. Models use Node-ORM so you’re not tied to a specific database.

Auto-routing

If your url’s follow the domain.com/controller/action/:id format, there’s no need to create any custom routing, it will just automatically load the controller/view if it’s found, and throw a 404 if it’s not.

Flexible Templates

You can choose from EJS, Handlebars, Hogan, Jade or Mustache for templates. Less, Sass & Stylus are available for css pre-processors (with additional support for Bourbon, Axis & Nib libraries).

Boilerplates

Tesla uses a combination of npm and Bower to help create some useful boilerplates when setting up a new app. You can choose to have Tesla add things like jQuery, AngularJS, Foundation, etc. to your view templates automatically when it creates the project.

Auto-watch & LiveReload

Tesla utilizes the Gulp task runner to watch for file changes, restarting the server when necessary. It also comes with LiveReload out of the box to auto refresh your browser when files change.

Easy Configuration

Almost all of the server settings (port number, database settings, etc.) can be easily updated in the config file.

back to top

Installation

Prerequisites:

Node.js & NPM are the only absolute requirements, but it's highly recommended that you install Gulp as well:

$ npm install gulp  -g

While it's not required, Tesla is configured to use Gulp for the majority of it's tasks. If you have any trouble installing it, refer to the Gulp documentation for help.

Install Tesla

Once you have NPM up & running, getting Tesla installed is pretty painless:

$ npm install tesla-cli -g

Update Tesla

$ npm update tesla-cli -g
back to top

Quick Start

Now that you have the command-line tool installed, you can create your first app:

$ tesla mysite

This will create a new barebones site with the name "mysite". Next, install dependencies:

$ cd mysite && npm install

Start the server:

$ gulp

Once the server has started, simply point your browser to: http://localhost:3000

If you choose not to use Gulp, you can start the server by running node server.js. But using Gulp gives you some extras such as livereload, and watching for changes your files & restarting the server whenever necesary.

back to top

Setup Options

back to top

Basic Settings

As you've seen, firing up a basic barebones site is pretty easy, but it's also a bit boring. Tesla is a lot more powerful than that, and it comes with a number of options that lets you create a boilerplate site with much more useful features

back to top
MVC Scaffolding

Tesla includes a generator that will do the dirty work of creting & linking controllers, models & views for you. Let's say you have a databse of users that you want to interact with:

$ tesla generate user

This one command will give you basic CRUD functionality via a very simple JSON api. See the working with data section for more info on scaffolding as well as working with models, controllers & views.

back to top
HTML templating engines

By default, Tesla use Jade for HTML templates, but it supports 5 different templating languages:

Options:

Example:

$ tesla myapp --html handlebars
back to top
CSS pre-processors

The default setting will just use plain ol' regular CSS. But if you want to use a css preprocessor, you have three options:

Options:

Example:

$ tesla myapp --css stylus
back to top
CSS helper libraries

Options:

NOTE: These helper libraries aren't fully tested yet, so please report any bugs you may find.
back to top

Front-End Tools

Tesla utilizes Bower to let you quickly add many of your favorite front-end tools such as jQuery, Angular or Bootstrap. If you select any of these options, the package(s) will be added to your bower file, and any javascript or css dependencies will automatically added to the default views.

back to top
JavaScript Application Frameworks

Options:

Example:

$ tesla myapp --backbone
back to top
JavaScript Libraries

Options:

Example:

$ tesla myapp --zepto
back to top
CSS Frameworks

Options:

Example:

$ tesla myapp --gumby
back to top

Real World Examples:

You can combine any number of the above options to customize your application to your liking:

Example 01: Create an app called foobar that uses EJS, Sass, AngularJS, & jQuery

$ tesla foobar --html ejs --css sass --angular --jquery

Example 02: Create an app called coil using Handlebars, Stylus, Axis, Foundation, Ember & jQuery

$ tesla coil --html handlebars --css stylus --axis --foundation --ember --jquery

All Tesla CLI Options:

Below is a reference listing all of the available options for the command-line tool:

Usage: tesla [options]

Options:

// BASIC SETTINGS
-H, --html <engine>  templating engine: (ejs|handlebars|hogan|jade|mustache) (defaults to Jade)
-C, --css <engine>   add stylesheet support (less|sass|stylus) (defaults to vanilla css)
-V, --version        output the version number
-F, --force          force on non-empty directory

// PRE-PROCESSOR LIBRARIES
--axis               add Axis support for Stylus
--bourbon            add Bourbon support for Sass
--nib                add Nib support for Stylus

// FE FRAMEWORKS
--angular            add support for AngularJS
--backbone           add support for BACKBONE.JS
--ember              add support for Ember.js

// JS LIBRARIES
--jquery             add support for jQuery
--modernizr           add support for Modernizr
--zepto              add support for Zepto.js

// CSS FRAMEWORKS
--bootstrap          add support for Bootstrap
--foundation         add support for Foundation
--gumby              add support for Gumby
--skeleton           add support for Skeleton

// OTHER SETTINGS
generate <name>      generate new model + controller with basic CRUD functionality
start                start the web server (still a bit buggy, best just just run "gulp" for now)
back to top

Configuration

All configuration for Tesla is specified in the config folder, particularly the config.js file and the env files. This is where you will need to specify your application name, database connection, and any other settings you would like to customize.

back to top
Default config file: config.js

Most default settings can be set & updated here:

app.site = {
    name : "tesla.js", // the name of your app
}

app.config = app.site = {
    name : "tesla-js", // the name of you app
}

app.config = {
    port : 3000, // port to run the server on

    prettify : {
        html : true, // whether to pretify html
        css : true, // whether to pretify css
        js : true // whether to pretify js
    },

    cache : false, // whether to use caching

    api : {
        enabled : true,
        format : 'json',
        access : '*'
    },

    engines : {
        html: "hbs", // options: [jade|ejs|haml|hjs|jshtml]
        css: "stylus", // options: [stylus|sass|less]
        cssLibrary: false, // options: [nib|axis]
    },
    root : rootPath,

    db : {
        url : "mongodb://:@mongohq.com:10074/dbname", // url to database
        driver: "mongodb"
    },

    jsonp : true, // allow jsonp requests
    secret : 'MYAPPSECRET',
    protocol : 'http://',
    autoLoad : true, // whether to attempt autoload controllers
    publicDir : './public',

    logging : {
        console: true, // whether to allow tesla to log messages to the node console
        files: false // this doesn't do anything yet
    }
}
}
back to top

Environmental Settings

To run with a different environment, just specify NODE_ENV as you call gulp:

$ NODE_ENV=test gulp

If you are using node instead of gulp, it is very similar:

$ NODE_ENV=test node server
back to top
Example config file for "development" environment: config/environment/development.js
// GET IP / DOMAIN
var interfaces = os.networkInterfaces();
var addresses = [];
for (k in interfaces) {
    for (k2 in interfaces[k]) {
        var address = interfaces[k][k2];
        if (address.family == 'IPv4' && !address.internal) {
            addresses.push(address.address)
        }
    }
}

var tesla = require('../../lib/tesla')(app);

// global settings
app.site.domain = addresses[0];
app.site.environment = "development";
app.site.url = app.config.protocol + app.site.domain + ':'  + app.config.port + '/'; // base url

// directories
app.site.dir = {
    css : app.site.url + "css/",
    img : app.site.url + "img/",
    lib : app.site.url + "lib/",
    js : app.site.url + "js/"
};
back to top

Routing

Tesla comes with an automatic routing system which should save you the trouble of manually creating routes for your site 99% of the time. The routing is based on the following URI structure:

http://localhost:3000/controller/action/:id

Let's say you called the following url:

http://localhost:3000/foo/bar

The router will attempt to find a matching controller in this order:

  1. app/controllers/fooController.js
  2. app/controllers/foo/indexController.js
  3. app/controllers/foo/barController.js

If it does not find a matching controller, it will use app/controllers/autoController.js and attempt to load one of the following views as a last resort:

  1. app/views/foo.js
  2. app/views/foo/index.js
  3. app/views/foo/bar.js
  4. app/views/foo/bar/index.js

If it's unable to find a matching controller or view, the router will throw a 404 error.

Custom Routes

If the default url scheme doesn't work for your site, you can easily create your own custom routes.

Routes are configured in the app/routes directory. The default router as well as a few sample routes can be found in: app/routes/_setup.js

HELLO WORLD

This is one of thie simplest routes. If you receive a request to domain.com/hello/world, it will load app/controllers/hello/worldController.

app.get("/hello/world", function(req, res) {
    require(controllers + 'hello/worldController')(app, res, res);
});

FOO BAR

This example loads the controller directly, and lets it handle its own routing. Take a look at app/controllers/fooController if you're curious how it works.

require(controllers + 'fooController')(app);

DYNAMIC ROUTING

This example shows how you can use dynamic routing to create RESTful CRUD style urls:

// EXAMPLE OF CRUD STYLE ROUTER & CONTROLLER
app.get("/:controller/:action/:id?", function(req, res) {
    require(controllers + req.params.controller + 'Controller')[req.params.action](app, req, res);
});

If you have Tesla running, try hitting the following URL's in your browser:

Have a look at app/controllers/crudController if you're curious how it works.

back to top

Working with data

Working with data & creating models in Tesla is super easy. It takes only 2 steps:

1. Add your database:
To work with data make sure you set the URL for your database (config.db.url) in the config file.

2. Generate a new model:
let's say you have a collection called "user" you want to use with your app, all you need to do is run the following command:

$ tesla generate user

This will create 2 new files for you:


Models

As long as your databse URL is set properly, this is all you need to do. However, you will almost certainly want to open up your new model and define the schema for your database table/collection.

In this file, you will see a block that looks something like this:

var Model = db.define("user", {
    created    : { type: "date", time: true },
    updated    : { type: "date", time: true }
    // _id     : { type: "text" },
    // name    : { type: "text", required: true },
    // isAdmin : { type: "boolean", defaultValue: false },
}, {
    validations: {
        // EXAMPLE VALIDATIONS
        // password: orm.enforce.security.password('luns5', 'Passowrd does not meet min security requirements.'),
        // email: orm.enforce.patterns.email('Please enter a valid email address.')
        // More Options : https://github.com/dresende/node-enforce
    }
});

This is wehere you will define what fields you want to be able to access. In the example above, this model only has access to "created" and "updated" fields. But it's almost certain that you will need to add more fields than this. There are a few commented out examples included to get you started.

Tesla uses Node-ORM to provide basic ORM functionality & databse abstraction. For more info on definifing models & validations, have a look at the ORM wiki.

Once you have your schema setup, that should be about all you need to do with the model in most cases. But feel free to muck about further down in the file if you need to do some more customization.

Controllers

By default, Tesla will serve up your data via a RESTful JSON api. If this is the result you want, you shouldn't need to make any changes to the generated controller. You get the following URI scheme by default:

http://localhost:3000/user/all                            // retrieve all records
http://localhost:3000/user/create?data&goes&here          // create a new record
http://localhost:3000/user/delete/:id                     // delete a record
http://localhost:3000/user/find?query&terms&here          // search for matching records
http://localhost:3000/user/update/:id                     // update a record

It's worth noting that delete & update require you to pass the databse ID as a url segment, while create & find accept arguments via GET parameters. Create maps each GET parameter to a field in the databse (POST & PUT support will come in the next iteration). For example, if you want to add the following data to your collection/table:

name: Bob
email: bob@marley.com

Assuming you've added the fields the the schema in your model, you would simple enter this into the browser:

http://localhost:3000/user/create?name=Bob&email=bob@marley.com

Similarly, if you want to retrieve all the records of people named Bob, you would build a request like this:

http://localhost:3000/user/find?name=Bob

And you will get back a JSON view similar to this:

[
    {
        name: "Bob"
        email: "bob@marley.com"
    },
    {
        name: "Bob"
        email: "bob@dylan.com"
    }
]

This is the default behavior, but if you would rather serve up a standard html, it's a simple change. Simply open up your config file and set "config.api.enabled" to "false". Now it will map the request to the appropriate view (assuming it exists). By default, you get 5 methods (all, create, delete, find, update). Continuing with our user example, you will get the following url > view mapping:

http://localhost:3000/user/all  >  app/views/user/all
http://localhost:3000/user/create?data&goes&here  >  app/views/user/create
http://localhost:3000/user/delete/:id  >  app/views/user/delete
http://localhost:3000/user/find?query&terms&here  >  app/views/user/find
http://localhost:3000/user/update/:id  >  app/views/user/update

These are all setup in the controller, however you will need to create the appropriate view files or you will get a 404 error. The data from each request (which was previously spit out as a JSON view) will be sent to the view as an object called "data".

back to top

Views

Views can use EJS, Handlebars, Hogan.js, Jade (default) or Mustache templates. See the appropriate documentation for your chosen templating language for more info on how to use it.

back to top

Troubleshooting

If you experience any issues during installation, here's a few tips that may help solve many common problems. If none of the below solve your problems, feel free to file a bug in the Github issue tracker.

Update NPM, Bower or Gulp

Sometimes you may find there is a weird error during install like npm's Error: ENOENT, usually updating those tools to the latest version solves the issue.

Updating NPM:
$ npm update -g npm
Updating Gulp:
$ npm update -g gulp
Updating Bower:
$ npm update -g bower

Cleaning NPM and Bower cache

NPM and Bower have a caching system for holding packages that you already installed. Cleaeing the cache often solves created by caching.

NPM Clean Cache:
$ npm cache clean
Bower Clean Cache:
$ bower cache clean
back to top

Heroku Quick Deployment

Before you start, make sure you have Heroku toolbelt installed and an accessible db instance if you have any models setup.

git init
git add .
git commit -m "initial version"
heroku apps:create
git push heroku master
back to top

Credits

Developed by: Jesse Weed
Inspired by: Express, Sails.js and MEAN.