Adding LESS.js support to your MEAN.js app
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.