Drupal 8 theming with Grunt & Libsass
Hit the ground running on Drupal 8 theming with Grunt and LibSass.
Here we are going to quickly run through how to set up the task runner, Grunt, to automate Sass compilation with Libsass - an increasingly popular port of the Ruby-based Sass library which has a truly incredible rate of compilation.
If you just want to get it set up and test it, follow the overview at the start of this article. If you want to understand a little more about how and why we do things, then read the whole thing!
TL; DR
- Install Node.js
- Create the file package.json in your theme's root and paste this code in to it
- Create the file Gruntfile.js in your theme's root and paste this code in to it
- In terminal, navigate to your theme's root and type the command: npm install --save-dev
- Still in terminal (theme's root) type the command: npm install -g grunt-cli
- Now run: grunt
- In your /sass folder, create a sass file name style.scss and start writing styles - they will auto compile
Install Node.js & Grunt
Before we start anything you’ll need to install Node.js. This is the platform Grunt runs on top of, but you don’t need to know too much about it; just go here and click the big ‘Install’ button.
Now let’s get Grunt. It’s installed on a project-by-project basis, so open your theme’s root folder and create a file called package.json. It needs to contain the following:
{
"name": "my-project",
"version": "0.1.0",
"devDependencies": {
"grunt": "^0.4.1",
}
}
See the Pen QbWmBp by Chris Liddell (@chriddell) on CodePen.
Name and version it whatever you like. The important bit in there are the devDependencies; this is how we specify what packages need to be installed on the project. To start we’re only specifying that this project needs Grunt version 0.4.1 at least (the tilde ‘~’ specifies it must be the most recent minor release - better explanation by a lovely StackOverflow user).
Node uses a package manager called NPM. This is very handy and allows us to easily manage our Node packages using the command line. "But I can't use the terminal!" Don’t worry, it's all straightforward stuff here.
So, using the terminal (or whatever equivalent you use - other command line tools are available) navigate to your theme’s root. Enter:
npm install
This command installs all the packages defined as dependencies in your package.json file. It creates the folder /node-modules inside your theme, which is where all of your Node packages are installed.
Before you can run any Grunt commands, you need to install the Grunt CLI (command line interface). We’ll install it globally so we don’t need a copy on every project.
Back to the terminal again. Run this command:
npm install -g grunt-cli
You’re now ready to install any node packages you think will help your project. There’s absolutely loads of great tools for front-end dev work - you can browse the library on the NPM website but, to be honest, you'd be better using Google to search for a specific task (e.g. "npm minifcation").
Libsass
Libsass is a wickedly fast port of the Sass engine. It translates Sass from Ruby to C++, allowing it to be “simple, fast and easy to integrate”. It’s quickly gaining traction with a lot of developers because of its rapid compile times; an area where Ruby-based Sass is a bit of a drag.
In order to use LibSass, we need a way to implement it. LibSass is a library. Think of it in the same way as the physical building of the same name, we need a way to check it’s books out.
Because we’re set up on Node, we’re going to use an implementer called node-sass. Node-sass is a node wrapper for libsass, so it’s perfect for this project. Install it on your project using:
npm install --save-dev node-sass
Check your package.json file; it will have updated its dependencies.
Grunt-sass
Next up, grunt-sass. This is a node package which will do the actual compiling of Sass files into CSS. No prizes for guessing how it's installed:
npm install --save-dev grunt-sass
Just to make things a bit easier to compile, let’s also install grunt-contrib-watch. We’ll tell this package to watch our Sass files and automatically compile them when they change with grunt-sass.
npm install --save-dev grunt-contrib-watch
Go ahead and download the livereload browser extension too - this connects your browser with grunt-contrib-watch, and will automagically reload your browser as your writing new styles.
We're getting closer...
We've now got a package.json file which looks like this:
{
"name": "my-project",
"version": "0.1.0",
"devDependencies": {
"grunt": "^0.4.1",
"node-sass": "^2.1.1",
"grunt-sass": "^0.16.0",
"grunt-contrib-watch": "~0.6.1"
}
}
See the Pen package.json final by Chris Liddell (@chriddell) on CodePen.
Now we create a file to tell grunt what tasks to run and how. Create a file in your theme’s root named Gruntfile.js and paste the following in to it:
module.exports = function (grunt) {
"use strict";
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
prod: {
options: {
outputStyle: 'compressed'
},
files: {
'./css/style.css': './sass/style.scss',
}
},
dev: {
options: {
outputStyle: 'expanded'
},
files: {
'./css/style.css': './sass/style.scss',
}
}
},
watch: {
options: {
livereload: true,
},
css: {
files: ['./sass/**/*.scss'],
tasks: ['sass:dev'],
options: {
spawn: false
}
},
livereload: {
options: {
livereload:true
},
files:[
'./css/*.css',
]
}
}
});
// Load tasks...
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
// Default task.
grunt.registerTask('default', ['watch']);
};
See the Pen JdjzQx by Chris Liddell (@chriddell) on CodePen.
These are essentially the default configuration options for grunt-sass and grunt-contrib-watch. All the declarations from sass/style.scss will be compiled in to css/style.css, leaving you free to set up your /sass folder any way you wish - so long as your style.scss file imports everything. I personally like to set my sass folders up using a structure based on SMACSS, with different partials for any styles I think should live together.
Try it out
Again, in terminal in your theme's root, type:
grunt
The 'watch' task will start. Any changes you make in your /sass folder should be reflected in css/style.css. Level complete!
Hopefully this article has made you feel less afraid of things like Grunt and terminal, and given you a taste of what's possible when we embrace alien tools and techniques.
Here some recommended reading for getting the most out of grunt and node packages:
- Getting started - Grunt: The Javascript Task Runner
- Grunt for people who think things like Grunt are weird and hard
- Github - grunt-contrib-watch
If you have any questions or suggestions feel free to tweet or DM us.