Launching apps with Yeoman

From creation to deployment on Heroku

Mike King
console.log(‘yo!’)

--

The front-end web stack provides a plethora of new tools to kick-start development and build out robust, scalable applications. However, when it comes to publishing and deployment, most workflows are catered to server-side technologies. With Yeoman and Heroku, you can architect your workflow around the same technologies and automate your production processes.

Prerequisites

This workflow follows the assumption that you have the following technologies available and are comfortable working in the command line:

Getting Started

If you already have an existing Yeoman app, you can skip to the Building for Production section below (or check out the TL;DR here).

Yeoman mascot

Yeoman is an opinionated client-side stack, composed of several tools and libraries for scaffolding workflows to create modern web apps. Yeoman is composed of three tools: Yo (a scaffolding tool), Grunt (a task runner), and Bower (a package manager).

To get started, we’ll need to install Yeoman globally using node’s package manager:

$ npm install -g yo

Yeoman’s scaffolding ability is built around the concept of apps, so you’ll need to download generators for the different types of apps you want to build. Let’s grab the default web app generator:

$ npm install -g generator-webapp

There’s over 500 app generators for Yeoman including Angular, Backbone, Ember, and even WordPress. A list of available generators can be accessed from the website or on the command-line, or you can write your own if your so inclined.

Scaffolding

To scaffold out a web app, you want to be in the directory that the app will be created in:

$ mkdir webapp && cd webapp
$ yo webapp

The web app generator is composed of a HTML5 Boilerplate, jQuery, and a Gruntfile.js file to build your app. Depending on the generator, Yeoman also provides options for adding additional technologies during installation like CSS Preprocessors (SASS/LESS), CSS Frameworks (Foundation, Bootstrap, etc.), and JS libraries like Modernizr.

Scaffolding a web app
with Yeoman

Version Control

For Git, we want to commit everything except our apps dependencies, so Yeoman scaffolds a .gitignore file with everything you need pre-filled. The reason you don’t want to check in the dependencies is because 1.) they can make your commits/repos unneccesarily large, and 2.) all of the dependencies (& their versions) are listed in manifests which are used by npm and Bower. So to keep your projects lightweight, you only need to check in code/files that you modify.

You can initialize a git repo as soon as scaffolding is complete.

$ git init
$ git add -A
$ git commit -m 'Initial Commit'
$ git remote add origin git@github.user/project.git
$ git push -u origin master

Writing your app

Once the scaffolding process is complete and your setup with version control, you can start writing code for your app. Everything specific to your app (HTML/CSS/JS) lives inside of the app folder, while everything specific to your build process (Gruntfile.js, package.json, node_modules, etc.) sits just outside of the app folder.

Running the following will launch your app in a new browser tab/window:

$ grunt serve

Yeoman comes with LiveReload built in, so as you make and save changes to your project, the browser automagically refreshes to display the recent changes. Sweet!

Building for Production

Alright, so we’ve written our code and we’re ready to get it deployed to a server. This is where Grunt really shines. If you didn’t notice, during the scaffolding process, Yeoman downloaded a bunch of packages in to the ‘node_modules’ directory of your app. All of those packages are tasks that Grunt runs to build and prepare your app for production, including checking your JavaScript for errors, compiling CSS preprocessors, minifying & obfuscating assets, and moving all of those prepared files to a production folder.

To build your project for production, run the following:

$ grunt build

You’ll notice that after the first time you run the build tasks, Grunt creates a ‘dist’ directory; this directory is where all of your production assets live. When you’re ready to deploy your app to a server, this is the directory you want to deploy.

Setting up Heroku

Yeoman apps are essentially composed of static, front-end assets (HTML/CSS/JS), so to deploy on a cloud service like Heroku, we need to setup a server and tell Heroku how to launch our app. This is actually pretty simple, since Heroku supports Node.

package.json

First, we’ll need a package.json for our app so Heroku recognizes it as a Node app. We already have one for our app in the main directory, but there’s a lot of cruft in it that we don’t need for production. Let’s create a new one just for our newly created ‘dist’ directory:

$ cd dist && npm init

npm init’ scaffolds a new package.json by walking you through a series of questions. All of the answers can be whatever you want, but make sure to take take note of the entry point; in this instance we’ll name our entry point ‘web.js’, but it could be anything “.js”. This will make sense here shortly.

package.json scaffolding using ‘npm init’

Express & Gzippo

For our server, we’ll use Express, a web app framework for node, to serve up our static site, Morgan, an http logger middleware for node, and Gzippo to serve speedy gzipped assets. Inside of our ‘dist’ directory, lets install these tools:

$ npm install express morgan gzippo --save

web.js

Now that we have our server framework in place, we’ll need to create a server file that tells Node what to do with our app. This is where the ‘web.js’ comes in to place. Create a ‘web.js’ file and add the following to the file:

var express = require('express');
var http = require('http');
var gzippo = require('gzippo');
var logger = require('morgan');
var app = express();
app.use(logger());
app.use(gzippo.staticGzip('' + __dirname));
var server = http.createServer(app);
server.listen(process.env.PORT || 5000);

Procfile

So now that Node knows what to do with our app on the server, let’s tell Heroku how to start our app as well. Create a ‘Procfile’ file and add the following to the file:

web: node web.js

Git

We’ll also be versioning our production code as well, so we’ll create a local git repo just for production inside of our current git repo and commit those files locally. First lets create a .gitignore file to ignore our ‘node_modules’ directory:

# Ignore pattern for Productionnode_modules

Now let’s create a git repo and commit everything:

$ git init
$ git add -A
$ git commit -m ‘Initial Commit’

Heroku

Now we have everything ready locally for Heroku, so lets setup the app online.

$ heroku create <app_name>

App names are optional, so if you don’t supply one, Heroku will randomly generate on for you. Make sure to take note of the git address for the app, you’ll need this in the next step.

Creating an app using ‘heroku create’

Deployment

Cool, so we built an app using Yeoman and now we want to publish it for the world to see in all of its glory. Even though this workflow is centered around pushing to Heroku, you have a couple of options for deploying Yeoman apps, depending on your needs:

  1. For small apps (with no backend), you can deploy using Github pages
  2. For larger, more robust apps, you can deploy to the cloud using Heroku

Regardless of which option you choose, Grunt lets us do both with ease. First we’ll need a tool built just for deploying Yeoman apps called grunt build control. Lets install it in our main app directory:

$ cd ../ && npm install grunt-build-control --save-dev

Grunt build control allows us to version and deploy our production code automatically with a single Grunt task. We just need to configure the new task inside of our Gruntfile.js file.

buildcontrol: {
options: {
dir: 'dist',
commit: true,
push: true,
message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
},
heroku: {
options: {
remote: 'git@heroku.com:dry-chamber-1376.git',
branch: 'master'
}
}
}

If your deploying to a Github page, just change the property for the task like the following:

 pages: {
options: {
remote: 'git@github.user/project.git',
branch: 'gh-pages'
}
}

Let’s also add shortcut for our task to make it easy for us to remember:

grunt.registerTask('deploy', ['buildcontrol']);

Now after we configure our Heroku setup, we can deploy using ‘grunt deploy’. More configuration options are available for grunt build control, so check out the documentation on the Github page.

Before we have lift off, lets make a few last modifications to our Gruntfile.js file. Remember all those files we created in our production folder for Heroku? Well, our Grunt task for creating the production build in the ‘dist’ folder wipes everything clean each time you run ‘grunt build’, so to keep from losing our work, we need to tell the clean task to ignore the new files we created:

// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/*',
'!<%= yeoman.dist %>/.git{,*/}*',
'!<%= yeoman.dist %>/Procfile',
'!<%= yeoman.dist %>/package.json',
'!<%= yeoman.dist %>/web.js',
'!<%= yeoman.dist %>/node_modules'
]
}]
},
server: '.tmp'
}

Now we can safely run ‘grunt build’ for later productions. Make sure to commit the changes to your Gruntfile.js and package.json before deploying.

Scaffold app… check.

Setup version control… check

Create production build… check

Configured server… check…

Lift off in 3… 2… 1…

$ grunt deploy 

Depending on your Yeoman app, you may need to scale up a web worker on Heroku for it to run:

$ heroku ps:scale web=1

Now you can open your app and revel in all its glory:

$ cd dist && heroku open

TL;DR

Familiar with Yeoman? Here’s the shorter version to get you up and running on Heroku.

--

--

Mike King
console.log(‘yo!’)

Creative Developer | Design ⤫ Animation ⤫ Technology