Building Web Apps Faster Using Angus

By  on  

Nick's outstanding utility, Angus, has changed! Click here to read an updated post!

When it comes to building web apps, there are a couple of tools available that help you develop faster. There's GruntJS, GulpJS, Brunch and others which streamline your workflow by doing a series of build tasks:

  • Test the code
  • Clean the build directory
  • Copy source files to the build folder
  • Do some magic tricks on your copied files, such as replacing variable names.
  • Compile Less or Sass files
  • Dynamically generate script tags for your index.html
  • Run a webserver to test out your app locally
  • Watch for code changes and re-build
  • ...

gruntcli

These tools do an outstanding job of helping you develop your web app faster. Huzzah!

Let's Build Another App!

Once you have finished your app and have started on a new project, you again would like to have a good build configuration. You have optimised your last app's build config so it builds as efficiently as possible, and it's got some cool gimmicks like that AWS S3 deploy task which you spent a couple of hours on last weekend.

Obviously, you want to reap the fruits of your hard labor and use those new and optimised build tasks in your new app as well. What to do now? There are a couple of ways.

Duplicating the Old App

You could just copy paste your old app folder, rename it and start working. The problem comes when you are improving your build setup even further. By now, there are likely newer and faster build tasks available, so you eagerly start implementing those in your new app. And wow, now there's a soft CSS refresh feature in the new app!

A few days later you need to bring an update to your old app. You painfully notice some cool features are missing in the old app's build config. Like that soft CSS refresh and the numerous performance updates you've made. What now?

Yeoman

One solution to the problem is Yeoman, a scaffolding tool. It generates your build config by asking questions, every time you make a new app. On its website you can find plenty of generators which include web frameworks and build tasks that have been set-up for you. These generators are maintained by many people and you will reap the benefits of their optimisations when you generate a new app.

yeoman

Generators aren't perfect however. When they are updated to include new tools and optimisations, you are stuck with your old build config. You can't simply update without generating and answering those scaffolding questions again. In addition, it is likely that your ideal build config requires changing or adding tasks such as the AWS S3 deploy which you need for your particular client.

yeoman2

The problem is that at the end of the day, you are again duplicating logic. When you have several apps, it is very likely that the build steps are similar if not identical. If you want to change something there or add a cool new build feature to many apps, you're out of luck.

Don't Repeat Yourself

A build config is just like any other code. You should not repeat yourself and you want to re-use your build config across different apps. What if there was a way to use one build configuration for all your apps?

Introducing Angus

Amid growing frustration with the state of things, I decided to make a generic and pre-configured build framework called Angus.

angus

Angus is a pre-configured build framework that you simply clone as a git repository. Inside this repo, you build your apps inside an apps/ folder which gets ignored by the Angus repo. For each app, you can define which libraries and build steps you would like to use. Every build task is already configured to work with other tasks.

The framework uses GruntJS to do all build steps. The cool thing is that you don't need to configure anything, you just need to tell which tasks you'd like to enable per app.

Project Structure

angus/   <-- angus repository
    Gruntfile.js
    grunt/   <-- generic build tasks
    apps/
        hello-world/
        my-second-app/    <-- app sub repository
            assets/
            scss/
            app.js
            config.js
            index.html

Apps Inside!

Unknown to many, Git repositories can actually exist within each other without using rocket science like submodules. Inside Angus, the apps/ folder gets ignored by git. You can safely create sub-folders inside apps/ which have their own repositories! To do so, simply create a folder inside the apps/ folder and run git init.

Given this structure, you can develop as many apps as you like without having to generate or adjust build configurations.

Configuring Each App

Every app inside Angus has its own configuration file, config.js. In this file, you can define Bower libraries and tell Angus which files from Bower you actually need. When including Bootstrap for instance, you may only really need a couple of .scss files.

**Example config file**
packages: [
    'angular',
    'bootstrap-sass-official'
],
// A list of files which this app will actually use from the bower packages above.
// Angus will look inside bower_components/ for these files.
libIncludes: {
    js: [
        'angular/angular.js'
    ],
    scss: [
        // Core variables and mixins
        'bootstrap-sass-official/assets/stylesheets/bootstrap/_variables.scss',
        'bootstrap-sass-official/assets/stylesheets/bootstrap/_mixins.scss',
        'bootstrap-sass-official/assets/stylesheets/bootstrap/_grid.scss'
    ]
}

Running the App

Simply run grunt dev, and Angus takes care of the rest. By default it will launch the hello-world application, but you can pass the —app=your-app parameter or change the config.json file in the root Angus folder.

Angus will automatically install Bower packages, auto include libraries and serve your app. It comes with [pushState support](http://diveintohtml5.info/history.html), auto-refresh on code changes and soft CSS refresh on CSS changes.

Deploying

Angus also includes a grunt prod command, which takes care of minification, uglifying and concatenating. The output of your files will be inside the dist/prod/ folder. You can even deploy directly to Amazon S3 with one command.

Additional Tasks

You can easily enable additional tasks you would like your app to execute. If you're running AngularJS, chances are you'll be wanting to use common build tasks specific to AngularJS such as template minifying, constants generation and the ng-min library.

The cool thing is, these tasks are already preconfigured! You just need to enable them as follows in your config.js file:

// In addition to the default task list (core/defaultTasks.js), also execute these
gruntTasksAdd: [
    'html2js',
    'ngconstant',
    'ngmin',
    'karma'
],

The Future

Angus is still a very fresh project, and I encourage you to help out by checking out the source code and sending pull requests. In the future, we may even switch to newer tools such as GulpJS or Brunch, but with the same philosophy. Don't repeat yourself!

I hope I have given you fresh insights into the build process of web apps, and how Angus can increase your productivity. Give it a try and let me know what you think!

Nick Janssen

About Nick Janssen

Nick Janssen is a full-stack web developer with a passion for creating cool applications, originally from Belgium.

Recent Features

  • By
    Creating Scrolling Parallax Effects with CSS

    Introduction For quite a long time now websites with the so called "parallax" effect have been really popular. In case you have not heard of this effect, it basically includes different layers of images that are moving in different directions or with different speed. This leads to a...

  • By
    5 Awesome New Mozilla Technologies You&#8217;ve Never Heard Of

    My trip to Mozilla Summit 2013 was incredible.  I've spent so much time focusing on my project that I had lost sight of all of the great work Mozillians were putting out.  MozSummit provided the perfect reminder of how brilliant my colleagues are and how much...

Incredible Demos

  • By
    Translate Content with the Google Translate API and JavaScript

    Note:  For this tutorial, I'm using version1 of the Google Translate API.  A newer REST-based version is available. In an ideal world, all websites would have a feature that allowed the user to translate a website into their native language (or even more ideally, translation would be...

  • By
    Simple Image Lazy Load and Fade

    One of the quickest and easiest website performance optimizations is decreasing image loading.  That means a variety of things, including minifying images with tools like ImageOptim and TinyPNG, using data URIs and sprites, and lazy loading images.  It's a bit jarring when you're lazy loading images and they just...

Discussion

  1. It’s actually not the case that you must “answer” generator questions again, while using Yeoman. Having built a number of generators myself, I know that any good generator will store configuration details in the package.json file.

  2. Nice concept, will check it out. I’m using more and more Node tools lately and was trying to think of a clean way to speed this process up :)

  3. Tyler

    Excellent concept and great tutorial. I will recommend this to friends in the future.

  4. Say yeah for Angus. It can’t be more easier for me to DRY config files.

  5. moritz

    This article needs to be updated, the example is based on grunt, he did the switch to gulp.

    Nice system anyway! We did something similar with grunt/gulp and process-html and a lot of for-each loops. It doesnt work well with many Apps in the app Folder. We got also some global folders for global scss, like the bower part, but managed by our own.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!