Getting Started With SCSS-Lint
As surprising as it might sound, writing working code is actually the easy part when developing a website, application or any piece of software. Making the whole thing scalable, tested, properly documented and easy to contribute to is the hard part.
One part is having a code base which is both clean and consistent. Clean, because maintaining ugly 'weird' code is definitely not a pleasure and consistent because it makes maintaining the code base easier and faster. If code looks the same everywhere in the software, then it should be quite fast to get used to the way it's written.
When it comes to Sass, there are a couple of things you can do to make your code clean and consistent. The first one would be to respect some coding guidelines, such as CSS Guidelines and Sass Guidelines. The other thing is to lint your codebase.
If you are not familiar with the word lint, here is what Wikipedia says:
In computer programming, lint was the name originally given to a particular program that flagged some suspicious and non-portable constructs (likely to be bugs) in C language source code. The term is now applied generically to tools that flag suspicious usage in software written in any computer language.
What would be a suspicious usage in Sass? It depends on how you define suspicious but, more broadly speaking, it could simply be a matter of making sure the stylesheet remains easily readable and not complex. One example would be to limit the usage of selector nesting to a single level for instance.
To lint our Sass code base, there is one hell of a tool called SCSS-lint. Now let's start with the bad news: SCSS-lint is a Ruby gem and no matter how you run it (CLI, Grunt, Gulp…), you will need to install this gem beforehand. On the bright side, some lovely folks are currently developing a port of SCSS-lint as a npm package, so we might get rid of this tedious extra step sooner or later. Right. Let's get this over with:
$ gem install scss_lint
Note: the gem is called scss_lint
for naming reason but the command line tool actually is scss-lint
. And the library is called SCSS-lint. Because it was not complex enough… :)
Getting starting with the CLI tool
SCSS-lint comes with a lot of options. Actually, so many that it might be a little overwhelming at first. Fortunately, there are actually not so many of those that we'll use frequently, so let's have a look at these.
Through the -c
or --config
option, you can pass the path to a configuration file that will be helpful to define which rules you want to apply to your codebase. For example:
$ scss-lint . --config .scss-lint.yml
Depending on your project, you might want to use the -e
or --exclude
option to exclude some files or folders from the linting process. For instance, you might not want to lint your third-party libraries or your node modules. For example
$ scss-lint . --exclude ./node_modules/**/*
For more complex usage of --exclude
, you can define it in the configuration file passed through --config
.
There are other options but I feel like this is more than enough to get started.
The first argument passed to scss-lint
is the folder to run on. If omitted, it will default to .
, the current folder. If you want to specify a specific folder, you can:
scss-lint ./assets/stylesheets
Configuring the linters
Now that we are ready to lint our Sass code base, we need to define which rules we should stick to. SCSS-lint has a load of linters, as they are called, so much that listing them all here would be too long. I recommend you go through the linters documentation.
The idea is that you create a YAML file at the root of your project, containing all your linting configuration. As a default, SCSS-lint will try to look for a .scss-lint.yml
file in the current folder so I recommend you name your file like this. However if you prefer another name, you can; be sure to pass it with the --config
option, that's all.
Sass Guidelines has a configuration file ready for you to grab and use in your project. Be sure to have a more in-depth look if you want to customise things, but all in all it should do the trick.
Linting on committing
One neat thing to do is to make sure the code is clean (linted) when committing with the help of a pre-commit hook. I played a bit with Sass testing and pre-commit hooks in a previous article here at SitePoint entitled testing a Sass library.
In case you are not sure what a pre-commit hook is, basically it is a mechanism aiming at running some operations before a commit being applied. If any of the operations performed raises an error, then the commit gets aborted.
Making sure the code is linted before committing to the remote repository is the perfect use case for a Git hook. In this section, we'll see how we can set this up in a very easy way.
To do so, we are going to use a very lightweight npm package providing support for Git hooks through the package.json
file direction. There are a lot of libraries to do so, but I personally opted for pre-commit. Here is what it looks like:
{
"scripts": {
"lint": "scss-lint ."
},
"pre-commit": [
"lint"
]
}
When committing, the pre-commit hook fires and runs the lint
npm script (exactly like npm run lint
). The lint
npm script, as you can see from the code, runs the scss-lint .
command. If SCSS-lint returns an error, the commit is aborted and the code needs to be fixed for the commit to pass.
If you run SCSS-lint through Gulp, Grunt or whatever else, you can run a task in the lint
npm script instead of using the scss-lint
binary directly. Along the same lines, you can pass options like --config
or --exclude
.
Final thoughts
We can always go further, but I think this is a good introduction to SCSS-lint, and we can actually use it on existing and new projects in a simple yet powerful way.
No reason to keep committing dirty code anymore folks, lint it before pushing it!