Working on a recent project using MEAN.js I wanted to add support for managing my styles with LESS.js. After building the application using the yeoman generator I was a little surprised that it didn't make use of if by default. Though adding it to the grunt configuration is easy and only takes a minute.

Installing dependencies

First you will need to install the less and grunt-contib-less packages using npm.

$ npm install --save less grunt-contrib-less

Optionally add a folder for .less sources

Personally I like to keep source files like less and scss out of my public folder. This is not really a requirement though I find it easier to organize things like this.

$ mkdir -p assets/less

Configuring Grunt

Adding the watcher

Next you will need to tell Grunt how to handle .less files and update the file watchers. Open up gruntfile.js in the root of your MEAN.js app and in the initConfig.watch options, add a new option for less files under the clientCSS option. I named mine clientLESS but you can enter any you like so long as it is unique.

grunt.initConfig({
            pkg: grunt.file.readJSON('package.json'),
            watch: {
                ...
                clientCSS: {...}
                clientLESS: {
                    files: ['assets/less/*.less','public/modules/**/*.less'],
                    tasks: ['less']
                }
            }
        ...

Note: If you decided not to create an assets folder then you can remove the first option in files.

Configuring less

Now tell the less configuration where to find source files and what to do with them. I chose to consolidate all the styles into the application core.css. Since this is an AngularJS application it is best to have all the needed styles available right away. I added the following below the csslint configuration.

less: {
    development: {
        options: {
            paths: []
        },
        files: [{
            src: ['assets/less/*.less', 'public/modules/**/*.less'],
            dest: 'public/modules/core/css/core.css'
        }]
    },
    production: {
        options: {
            paths: []
        },
        files: [{
            src: ['assets/less/*.less', 'public/modules/**/*.less'],
            dest: 'public/modules/core/css/core.css'
        }]
    }
}

Having a development and production environment specification are required and things will fail like this without them.

Warning: Object #<Object> has no method 'indexOf' Used --force, continuing.

For now they are the same but once the application is ready to deploy the production settings could be updated to run additional optimizations on your styles.

Updating the lint task to run less

Last you need to add less to the lint grunt.registerTask before the csslint task. It should look like this:

grunt.registerTask('lint', ['jshint', 'less', 'csslint']);

Conclusion

Setting this up was fairly straight forward, but I did use yeoman to generate the site. If you started by checking out source from github or some other path things may not match. Though there should be enough here to get it setup.

An additional concern that popped into mind is upgrading. I have not had to migrate to a new version yet and can not guarantee that these changes to the gruntfile will not be overwritten at that time. Perhaps a better solution of including an external configuration should be looked at, or adding it as an option to the yeoman generator.