Learn To Code With Style: Use Linters!

May 01, 2017Vincent Langlet5 min read

thumbnail

Are you tired of always writing the same comments on others pull requests? Are you tired of always reading the same comments on your pull requests? Stop wasting time, here’s the solution.

Step One: Install linters on your project

For your php files

Inspired by this CodeSniffer and PhpStorm Code Inspection article, we can install phpcs with a specific coding standard directly on your project.

Install CodeSniffer

composer require --dev squizlabs/php_codesniffer

Install a coding standard

When I start working on a Symfony2 project, it was with the djoos/Symfony2-coding-standard repository.

composer require --dev escapestudios/symfony2-coding-standard

Now i made my own my fork with more rules, try it!

composer require --dev vincentlanglet/symfony3-custom-coding-standard

Use it

Let’s try with this file

// yourfile.php

<?php

class Entity {
    function getVariable() {
        return $this->variable;
    }

    function setVariable($newValue) {
        $this->variable = $newValue;
    }

    private $variable;
}

The following command

vendor/bin/phpcs --standard=../../../../vincentlanglet/symfony3-custom-coding-standard/Symfony3Custom yourfile.php

will return error messages
Phpcs

that you can easily correct

<?php

namespace AppBundle\Entity;

/**
 * Class Entity
 *
 * @package AppBundle\Entity
 */
class Entity
{
    /**
     * @var string
     */
    private $variable;

    /**
     * @return string
     */
    public function getVariable()
    {
        return $this->variable;
    }

    /**
     * @param string $newValue
     */
    public function setVariable($newValue)
    {
        $this->variable = $newValue;
    }
}

NB: If you are tired to write --standard=../../../../vincentlanglet/symfony3-custom-coding-standard/Symfony3Custom,
or if you need to configure phpcs to use it with PhpStorm, try

vendor/bin/phpcs --config-set default_standard ../../../../vincentlanglet/symfony3-custom-coding-standard/Symfony3Custom

You can find others options here.

For your javascript files

Let’s do the same with eslint.

Install eslint

npm install eslint --save-dev

Generate a configuration file

To start the configuration of eslint, use

./node_modules/.bin/eslint --init

After answering a few questions, it will generate a .eslintrc file configured like this

{
  "extends": "eslint:recommended",
  "rules": {
    "semi": ["error", "always"],
    "quotes": ["error", "double"]
  }
}
  • extends apply all the rules of eslint:recommended to your project. I recommend the airbnb config.
  • semi and quotes are extra rules. The first value is the error value of the rule.

Use it

Let’s try with this file

// yourfile.js

var object={
  'key': 3,
     "otherKey" :2
};

console.log(object)

The following command

./node_modules/.bin/eslint yourfile.js

will return error messages
Eslint

that you can easily correct

const object = {
  key: 3,
  otherKey: 2,
}

console.log(object)

Even for your css files

In the same way, you can lint your css files thanks to stylelint.

Install stylelint

npm install stylelint --save-dev

Write your configuration file

I recommend the stylelint-config-standard.

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

Now you have to create your .stylelintrc file, it works like your .eslintrc file:

{
  "extends": "stylelint-config-standard",
  "rules": {
    "string-quotes": "single"
  }
}

Use it

Let’s try with this file

/* yourfile.css */

.header {

}

body {
text-color: red;
margin-top: 10px;
margin-bottom: 10px;
margin: 0;
}

The following command

./node_modules/.bin/stylelint yourfile.css

will return error messages
Stylelint

that you can easily correct

body {
  color: red;
  margin: 10px 0;
}

Step Two: Use linters automatically before each commit

Use pre-commit hooks

Pre-commit hooks were already introduced in this article, but personally I prefer using a npm package.

Install pre-commit

npm install pre-commit --save-dev

Configure pre-commit

You just need to specify scripts you want to launch before committing in your package.json.
You could even launch tests before commits if you wanted.

{
  "name": "Something",
  "version": "0.0.0",
  "description": "Something else",
  "main": "index.js",
  "scripts": {
    "lint:php": "vendor/bin/phpcs --standard=../../../../escapestudios/symfony2-coding-standard/Symfony2 *.php",
    "lint:js": "eslint *.js",
    "lint:css": "stylelint *.css"
  },
  "pre-commit": [
    "lint:php",
    "lint:js",
    "lint:css"
  ]
}

Use it

Just commit!

But don’t worry, you can still force a commit by telling git to skip the pre-commit hooks by simply committing using --no-verify.

Check only modified files to be more user-friendly

Running a lint process on a whole project is slow and linting results can be irrelevant. Ultimately you only want to lint files that will be committed. Lint-staged will be used to run linter on staged files, filtered by a specified glob pattern.

Install lint-staged

npm install lint-staged --save-dev

Configure lint-staged

Launch lint-staged with pre-commit and precise which linter you want to use for specific files pattern in your package.json.

{
  "name": "Something",
  "version": "0.0.0",
  "description": "Something else",
  "main": "index.js",
  "scripts": {
    "lint-staged": "lint-staged"
  },
  "lint-staged": {
    "*.php": "vendor/bin/phpcs --standard=../../../../escapestudios/symfony2-coding-standard/Symfony2",
    "*.js": "eslint",
    "*.css": "stylelint"
  },
  "pre-commit": [
    "lint-staged"
  ]
}

Use it

Wait

Vincent Langlet

Vincent Langlet

Web Developer at Theodo