Application on Express.js + Sass / Compass + CoffeeScript + Haml

Good afternoon!
I decided to share the experience of switching from Middleman (Ruby) to Express.js (Node.js) as a front-end developer tool.
I myself do back-end, so the article may not be very relevant, but hopefully useful to at least someone.

So, the task: to make an application on Node.js with support for compiling Sass (Compass), CoffeeScript and Haml “on the fly” while editing the corresponding files. To do this, we will use Express and Grunt to start the web server and perform compilation tasks, respectively.

First, we need Node itself. I prefer to use NVM (an analogue of RVM for Ruby) for its installation and version control.

We put NVM:
curl https://raw.github.com/creationix/nvm/master/install.sh | sh

And connect it:
source ~/.nvm/nvm.sh


Next, we install and connect the latest version of Node (at the moment it has not left 0.10. *, Therefore, to install the latest version, it is enough to register):
nvm install 0.10
nvm use 0.10


Now you can use Node itself with its npm package manager. We put Express and Grunt globally:
npm install -g express
npm install -g grunt-cli


Create an express application using express <project> -e:
express develop -e
cd develop

The -e option sets the base template engine to ejs, which will quietly render the usual html into which we will compile our haml. In order to show the application what needs to be done in this way, add the line in app.js to the app settings
app.engine('html', require('ejs').renderFile);


Immediately install all the necessary packages through npm:
npm install grunt-contrib-watch grunt-contrib-sass grunt-contrib-compass grunt-contrib-coffee grunt-contrib-haml grunt-express-server --save-dev

(the option --save-dev will write the necessary dependencies in our package.json so that you don’t lose them later)

Now we will install all other Express dependencies:
npm install


Well and the last: we create the Gruntfile file in which we will describe the necessary tasks:
touch Gruntfile.js


The preparation is finished! Now - for the tasks themselves. We write something in Gruntfile
module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // здесь будут настроенные нами таски
  });
  // здесь будут подключаться необходимые модули
  grunt.loadNpmTasks('');
  // а здесь - вызываться таски
  grunt.registerTask('default', ['']);
};


And we begin to fill it. First, connect all the necessary modules to loadNpmTasks:

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-haml');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-express-server');


Now we can begin to describe the compilation tasks (tasks):
we will store all the views in the views / folder, all js and coffee in javascripts /, all css and scss in stylesheets /.
Let's create some files for an example:
touch public/javascripts/x.coffee
touch public/stylesheets/s.scss
touch views/index.haml


And delete the default index.ejs we did not need:
rm views/index.ejs


All coffee can be compiled into one js, which we will use.
The set of tasks for compilation will look like this:
    haml : {
      dist: {
        files: {
          'views/index.html': 'views/index.haml'
        }
      }
    },
    sass : {
      dist: {
        files: {
          'public/stylesheets/s.css': 'public/stylesheets/s.scss'
        }
      }
    },
    coffee : {
       compile: {
        files: {
          'public/javascripts/x.js': ['public/javascripts/*.coffee']
        }
      }
    }


! For the haml task to work, the haml gem (and ruby, of course) must be installed and accessible on the system!

To use Compass instead of Sass, you need to replace the corresponding task (sass) with
  compass: {
      dev: {
        options: {
          sassDir: ['public/stylesheets'],
          cssDir: ['public/stylesheets'],
          environment: 'development'
        }
      }
    },


Now add task to execution in registerTask block:
grunt.registerTask('default', ['sass', 'coffee', 'haml']);

(compass instead of sass if necessary) We ’ll

execute gruntand see that the tasks successfully completed, and now in the corresponding folders you can find index.html, s.css and x.js.
It remains only to turn on the server and make the recompilation process automatic using watch. Gruntfile will turn out like this:

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // здесь будут настроенные нами таски
    watch : {
      haml : {
        files : 'views/*.haml',
        tasks : 'haml'
      },
      coffee : {
        files : 'public/javascripts/*.coffee',
        tasks : 'coffee'
      },
      sass : {
        files : 'public/stylesheets/*.scss',
        tasks : 'sass'
      },
      //  compass : {
      //    files: ['public/stylesheets/*.{scss,sass}'],
      //    tasks: ['compass']
      //  }
    },
    express : {
      dev: {
        options: {
          script: 'app.js'
        }
      }
    },
    haml : {
      dist: {
        files: {
          'views/index.html': 'views/index.haml'
        }
      }
    },
    sass : {
      dist: {
        files: {
          'public/stylesheets/s.css': 'public/stylesheets/s.scss'
        }
      }
    },
    compass: {
      dev: {
        options: {
          sassDir: ['public/stylesheets'],
          cssDir: ['public/stylesheets'],
          environment: 'development'
        }
      }
    },
    coffee : {
       compile: {
        files: {
          'public/javascripts/x.js': ['public/javascripts/*.coffee']
        }
      }
    }
  });
  // здесь будут подключаться необходимые модули
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-haml');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-express-server');
  // а здесь - вызываться таски
  grunt.registerTask('default', ['sass', 'coffee', 'haml', 'express', 'watch']);
};

(Accordingly, to use Compass, you will need to change the sass task to compass in the description of the watch task and in registering the default task)

Well, now gruntyou can use our application to launch it and all the necessary files will be compiled when the source code is changed.

Update: Livereload
Task watch can be configured on the livereload page.
To do this, add the appropriate options to the description of the watch task:
 watch : {
      options: {
        livereload: true,
        nospawn: true
      },
      haml : {
        files : 'views/*.haml',
        tasks : 'haml'
      },
      coffee : {
        files : 'public/javascripts/*.coffee',
        tasks : 'coffee'
      },
      // sass : {
      //   files : 'public/stylesheets/*.scss',
      //   tasks : 'sass'
      // },
      compass: {
        files: ['public/stylesheets/*.{scss,sass}'],
        tasks: ['compass']
      }
    }

And include the livereload script on the page, through the default port 35729
%script{src:"//localhost:35729/livereload.js"}


====================

Thanks to those who read!
In the following articles I plan to share my experience with Sails.js (Rails-like MVC on Node) and other joys of server-side JS.

Also popular now: