Jan 6, 2014

If you're writing configuration to manage your assets you're doing it wrong.

I grew up writing HTML, CSS and JavaScript like everyone else, but each time I opened a blank text document and starred at the page the awkward feeling crept in. My pinky finger still cringes from holding shift followed by <. Sure I could copy and paste in a template or use the HTML5 boilerplate, but that only saves keystrokes and does not make anything easier.

There are a new breed of web languages kids are learning, languages like LESS, Sass, Stylus, and CoffeeScript that are making their way into the mainstream with the help of tools like Grunt and Brunch. It is still early days. These tools have helped make modern web languages more accessible, but have added extra cognitive overhead in how we manage them. The Harp web server is the only tool that treats these modern web languages as first class citizens of the web.

When you use Harp, you choose what pre-compilers you want by saving your file with the appropriate extension, not by setting up some configuration and defining your input folder and output folders. It really doesn't get any easier!

For example, if I want to use LESS all I would need to do is save my stylesheet as styles.less. The Harp server then serves that as styles.css. This IS the killer feature and once you try it you will wonder how you put up with anything else before.

Look at how crazy it is you’re expected to do this:

module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    coffee: {
      compileBare: {
         options: {
           bare: true
         },
         files: {
           'path/to/result.js': 'path/to/source.coffee', // 1:1 compile
           'path/to/another.js': ['path/to/sources/*.coffee', 'path/to/more/*.coffee'] 
         }
       }
    },
    markdown: {
      all: {
        files: [
          {
            expand: true,
            src: 'docs/src/*.md',
            dest: 'docs/html/',
            ext: '.html'
          }
        ]
      }
    },
    jade: {
      compile: {
        options: {
          data: {
            debug: false
          }
        },
        files: {
          "path/to/dest.html": ["path/to/templates/*.jade", "another/path/tmpl.jade"]
        }
      }
    },
    stylus: {
      compile: {
        options: {
          paths: ['path/to/import', 'another/to/import'],
          urlfunc: 'embedurl', 
          use: [
            require('fluidity') 
          ],
          import: [      
            'foo',       
            'bar/moo' 
          ]
        },
        files: {
          'path/to/result.css': 'path/to/source.styl', 
          'path/to/another.css': ['path/to/sources/*.styl', 'path/to/more/*.styl'] 
        }
      }
    },
    sass: {                             
        dist: {                         
          options: {                    
            style: 'expanded'
          },
          files: {                      
            'main.css': '/css/main.scss',    
            'widgets.css': '/css/widgets.scss'
          }
        }
    },
    less: {
      development: {
        options: {
          paths: ["assets/css"]
        },
        files: {
          "path/to/result.css": "path/to/source.less"
        }
      },
      production: {
        options: {
          paths: ["assets/css"],
          cleancss: true
        },
        files: {
          "path/to/result.css": "path/to/source.less"
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-markdown');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-stylus');
  grunt.loadNpmTasks('grunt-contrib-jade');

  grunt.registerTask('default', ['less', 'sass', 'stylus', 'jade', 'markdown']);

};

This is part of the philosophy of Harp (http://harpjs.com/docs/development/rules) and Rule No. 1. Convention over Configuration. This rule applies to all supported pre-processors and templating languages Harp supports, and that list is growing.

But what about all the options, I hear you shouting, I want to have complete control over everything. To which I would reply, Harp is for people who SHIP software from day one.

That might have sounded harsh, so let me put it a different way. All these tools were designed to help developers in some ways while evaluating the risks and trade-offs. However the needs of developers change and the tools are forced to adapt over time to keep up. Sometimes at the cost of the projects original goals.

Grunt is great for managing every detail of a build chain, where Harp is designed for people who just want everything to get out of their way and stay out of the way from the beginning.

Since I have started using Harp, I have put more things online, and updated them more frequently than any other tool since I was introduced to the web in 1995.

What about file watching...

Harp comes with a production ready web server, and watches your files by default, no special options, no input folder, output folder, no compile command necessary.

So what is really going on under the hood? The Harp Server is automatically pre-compiling the asset and keeping them in memory, and since it does't write the file to disk it is fast—REALLY FAST. When you run the Harp server in production, we add extra caching to manage the memory consumption so things don't get out of hand.

The benefits of Harp kick in long before you even start writing your application or site, we identified one of the biggest problems with other solutions was the environment, and the time it takes to get started. Ask any seasoned developer writing Ruby and the will tell you all about Gem Hell. With Harp you really can go from zero to hello world in 3 minutes, batteries included.

1. Download Node (http://nodejs.org/download/)
2. [sudo] npm install harp -g
3. harp init my_awesome_site
4. harp server ./my_awesome_site

So now, quit writing configuration and start writing your application, seriously.

Discuss on Hacker News

Written by Rob Ellis