Declarative Build Configurations

By  on  

Some time ago I posted an article how you can build apps faster using a build tool called Angus. In the meantime the tool has gotten a whole lot better, embracing the concept of declarative build configurations. In this article I would like to show you what that means and how Angus can help you build web apps in a much faster way.

In The Restaurant

Gordon Ramsay

Imagine for a second you're sitting in a restaurant. You take a look at the menu. You decide that you would like a Pizza Vegeta today, because you're feeling healthy. Hmm!

Next, you stand up from your table. You walk to the kitchen. You start to delegate.

"You there! Take some dough and make it flat and round."

"And you! Chop some onions, tomatoes and bell peppers."

"Now you, grab the tomato sauce and cheese and put them on the dough."

"Put all those vegetables on the pizza and then put it in the oven for ten minutes!"

After ten minutes, you come back. You put the pizza on your plate, walk to your table and start eating.

GulpJS: A Case Study

Let's wake up, and take a look at a common build tool configuration from GulpJS.

gulp.task('clean', function(cb) {
  del(['build'], cb);
});

gulp.task('scripts', ['clean'], function() {
  return gulp.src(paths.scripts)
    .pipe(sourcemaps.init())
      .pipe(coffee())
      .pipe(uglify())
      .pipe(concat('all.min.js'))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('build/js'));
});

gulp.task('images', ['clean'], function() {
  return gulp.src(paths.images)
    .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest('build/img'));
});

gulp.task('watch', function() {
  gulp.watch(paths.scripts, ['scripts']);
  gulp.watch(paths.images, ['images']);
});

gulp.task('default', ['watch', 'scripts', 'images']);

If you compare this configuration with the absurd restaurant scene, it's essentially not that different. You're telling Gulp what to do, how to do it and when and where to get your compiled files.

Can we do better than that? What if there was a way to tell Gulp, "Hey, today I'd like a Pizza Vegeta."?

What if there was a tool, where you could say "Today I'd like to have an app that uses AngularJS, some bootstrap, karma as test runner, and hmmmm... I'll have Sass as my CSS compiler this time."

Angus, A Declarative Build Tool

angus

Having built a ton of apps, I've always found myself having to declare the same tasks over and over again, although they essentially stayed the same across my apps. Out of frustration with the state of things, I decided to create a tool called Angus that makes build configurations declarative.

Take a look at a common Angus configuration.

{
    bower: {
        packages: [
            'angular',
            'threejs',
            'Keypress',
            'underscore@1.7.0',
            'angular-ui-router',
            'hammerjs'
        ],
        filesNeeded: {
            js: [
                'angular/angular.js',
                'angular-ui-router/release/angular-ui-router.js',
                'Keypress/keypress.js',
                'hammerjs/hammer.min.js',
                'threejs/build/three.js',
                'underscore/underscore.js'
            ]
        }
    },
    usesAngularJS: true,
    testRunner: 'karma',
    cssCompiler: 'less'
};

In essence, I'm telling Angus which bower packages my app needs and which files to actually use from those bower packages. Next I'm declaring it uses AngularJS, Karma as its test runner and Less as its CSS compiler.

That's it. There are no other hidden configuration files. I just run angus dev from the command line and my app launches in the browser, ready to go.

Angus takes care of everything. It installs your bower packages, minifies your files, compiles your CSS, watches for changes and launches your app in a browser. But there's a lot more features.

Convention Over Configuration

Angus applies the concept of convention over configuration so that it doesn't burden the user with making unnecessary choices such as where to store the distributed files. For one, it requires you to layout your source files in a way that's common for web apps.

hello-world/
    bower_components/
    src/
        assets/
        style/
        core/
        index.html
    angus.config.js

This makes things a lot simpler. By having your source files structured in the same way for every app, Angus can automatically build your app without you having to specify where your source and library files are.

Next, all underlying tasks use this folder structure to build your app. All common tasks are pre-configured, Angus just tells them whether to execute or not based on your config file. Again, it's declarative.

In addition, it's a lot easier to maintain. For example, if you wanted to switch to another CSS compiler, it's simply a matter of enabling it in your config file.

Quick Start

Getting started with Angus is easy. Just install it with npm install -g angus.

Next, create a sample app by doing angus create hello-world. This will create a folder hello-world.

Inside this folder, run angus dev and open your browser to visit http://localhost:9000/.

That's it! For further information, please refer to the detailed readme on GitHub.

Conclusion

I hope that this article has given you new insights in how declarative build configurations can help you focus your efforts on your app and not your build process. Angus has gotten a lot of good feedback so far, and I invite you to try it out and make an opinion for yourself. If you have any questions I will be happy to answer them in the comments section below.

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

Incredible Demos

  • By
    PHP / MooTools 1.2 Accordion Helper

    The MooTools Accordion plugin seems to be the plugin that people seem to have the most problems with. It's an awesome plugin, so I can see why so many people want to use it, but I think that may be part of the problem.

  • By
    Multiple Background CSS Animations

    CSS background animation has been a hot topic for a long time, mostly because they look pretty sweet and don't require additional elements.  I was recently asked if it was possible to have multiple background animations on a given element and the answer is yes...with...

Discussion

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