Stylelint with SPFx integration

Are you TypeScript developer? I bet you use tslint in all your TypeScript projects! If not – start using it. SharePoint framework has tslint step which validates your code against tslint rules, which is awesome. More and more web developers today also use stylelint. Stylelint can be easily explained in just three words – linter for css/scss. Modern web developer (and of course modern SharePoint developer) has to write a lot of css or scss code. So why don’t we lint css code as well? Checkout increasing interest in stylelint at npmtrends:

SharePoint Framework in current version doesn’t have built-in stylelint support. However we can easily fix it with custom gulp subtask. Let’s do it right away!

Starter project

I use React template as starter project for my stylelint integration. This project has .scss files inside, which is perfect for us. Scaffold a project with

yo @microsoft/sharepoint

choose React as javascript framework and webpart as component type. You can find full working project here at GitHub.

stylelint

stylelint uses almost the same concepts as tslint. First of all you should create a configuration file, which describes your rules. You can do it in many different ways:

  • a stylelint property in package.json
  • a .stylelintrc file
  • a stylelint.config.js file exporting a JS object

You should describe all rules in this file or you can extend your configuration with set of predefined rules. I’m going to use stylelint-config-standard rule set. Here is the quote which gives us a hint about rules included in the set:

Turns on additional rules to enforce the common stylistic conventions found within a handful of CSS styleguides, including: The Idiomatic CSS Principles, Google's CSS Style Guide, Airbnb's Styleguide, and @mdo's Code Guide.

Another thing is that we use scss in SPFx and not css. That’s not an issue at all, because stylelint supports SASS syntax. We should install additional plugin to make sure that we can use scss specific rules and scss syntax as well. This plugin called stylelint-scss. Plugins system allows you to extend linting with non-trivial rules. There are a lot of plugins for stylelint. For example you can install plugins to check that your styles follow css architectural patterns – RSCSS, SUIT CSS, BEM selectors styles. With plugins you can check that you don’t have broken image links, your css tree is valid, color formats are good and many other things. It’s very powerful!

Add a new file .stylelintrc at the root of SPFx project. Taking into account everything I mentioned about extending rule set and plugins usage, the content of our .stylelintrc  will be:

{
  "extends": "stylelint-config-standard",
  "plugins": [
    "stylelint-scss"
  ],
  "rules": {
    "at-rule-no-unknown": null,
    "scss/at-rule-no-unknown": true
  }
}

While “extends” and “plugins” sections are pretty clear, a few notes regarding rules node. By default, css doesn’t understand @include keyword, that’s why we should disable it, then we enable it again with help of scss plugin, in order to check, that we don’t use @<something not supported by scss> in our files.

install dependencies

To make it work we should install a few dependencies. Of course that’s stylelint itself and stylelint plugins. How to integrate it into the SPFx? stylelint support different ways to do that – cli, gulp, webpack. cli doesn't look attractive for us. Webpack is not an option, because only webpack 4 is supported (SPFx uses webpack 3). Moreover in my opinion you should avoid heavy webpack customization to increase supportability of you app and safer transition between SPFx version. Gulp option works for us very well.

As a result, you should install below dependencies:

npm install stylelint stylelint-config-standard stylelint-scss gulp-stylelint --save-dev

vscode

For convenience I recommend you to install vscode stylelint plugin. It atomically highlights all stylelint issues in your files based on rules from stylelint configuration file.

gulpfile

The final step is to add subtask to your gulp file. It’s pretty simple, check out how your final gulpfile.js should look like:

'use strict';

const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');

const stylelint = require('gulp-stylelint');

build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);

/* stylelint sub task */
let styleLintSubTask = build.subTask('style-lint', (gulp) => {
  return gulp
    .src('src/**/*.scss')
    .pipe(stylelint({
      reporters: [
        { formatter: 'string', console: true }
      ]
    }));
});
/* end sub task */

build.rig.addPreBuildTask(styleLintSubTask);

build.initialize(gulp);

If you run gulp serve you…. will receive a few errors from stylelint task. The thing is, that default HelloWorld.module.scss has some minor lint issues, which can be easily resolved (you can see fixed version here, just a few spaces between fonts, one extra new line).

That’s it! Now you can make your SPFx styles even more solid and consistent! :)