Linters

# Linters

# Introduction

Using linters can help us writing better code. We've chosen Husky to execute linters on the stage files.

# Husky and lint-staged

Modern native Git hooks made easy Husky supports al native git hookes https://git-scm.com/docs/githooks (opens new window)

# Install

    npm install husky lint-staged --save-dev

# Configuration

Add hooks to package.json

    "husky": {
        "hooks": {
            "pre-commit": "lint-staged",
            "pre-push": "php artisan test"
        }
    },

Create a configuration file lint-staged.config.js

In this example we have added a pre-commit hook for checking php files

module.exports = {
  '**/*.php': ['php ./vendor/bin/php-cs-fixer fix --config .php-cs-fixer-config.php --allow-risky=yes'],
};

# Install pre-commit hooks

Run below command to install

    npx husky install

# Trouble shooting

In my first project everything workt fine, my second the hooks were not firing. beneath the solution to solve this:

npm install -D husky

npm set-script prepare "husky install" && npm run prepare

npx husky add .husky/pre-commit "npx lint-staged"

git commit -m "added husky and lint-stagged" // here you will notice the lint-staged checking the files with help of husky

# PHP CS Fixer

# install

composer require friendsofphp/php-cs-fixer

# Configuration

Create a configuration file .php-cs-fixer-config.php:

<?php

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

$finder = Finder::create()
    ->in(__DIR__)
    ->exclude(['bootstrap', 'storage', 'vendor'])
    ->name('*.php')
    ->name('_ide_helper')
    ->notName('*.blade.php')
    ->ignoreDotFiles(true)
    ->ignoreVCS(true);

return (new Config())
    ->setRules([
        '@PSR12' => true,
        'ordered_imports' => ['imports_order' => ['class', 'function', 'const'], 'sort_algorithm' => 'alpha'],
    ])
    ->setFinder($finder);

# ESLint

# Install

  npm install eslint --save-dev

# Config

Running below code wil generate a config file.

  npm init @eslint/config

Config file

module.exports = {
  'env': {
    'browser': true,
    'es2021': true,
  },
  'extends': [
    'eslint:recommended',
    'plugin:vue/recommended',
  ],
  'parserOptions': {
    'parser': 'babel-eslint',
    'ecmaVersion': 6,
  },
  'plugins': [
    'vue',
  ],
  'rules': {
    'indent': [
      'error',
      2,
      {
        'SwitchCase': 1,
      },
    ],
    'linebreak-style': [
      'error',
      'unix',
    ],
    'quotes': [
      'error',
      'single',
    ],
    'semi': [
      'error',
      'always',
    ],
    'prefer-const': ['error', {
      'destructuring': 'any',
      'ignoreReadBeforeAssign': false,
    }],
    'key-spacing': ['error', {
      'afterColon': true,
    }],
    'object-curly-spacing': ['error', 'always'],
    'comma-dangle': ['error', 'always-multiline'],
    'eol-last': ['error', 'always'],
    'nonblock-statement-body-position': ['error', 'below'],
    'vue/html-closing-bracket-newline': 'error',
    'vue/html-closing-bracket-spacing': 'error',
    'vue/prop-name-casing': 'error',
    'vue/max-attributes-per-line': ['error', {
      'singleline': 1,
      'multiline': 1,
    }],
    'vue/multi-word-component-names': 0,
  },
  'globals': {
    'module': false,
    'process': false,
    'require': false,
    'Config': false,
    'Echo': false,
    '$': false,
    'Nova': false,
    '__dirname': false,
  },
  overrides: [
    {
      files: [
        'webpack.mix.js',
        'ThemePlugin.js',
        '_templates/**',
        'docs/.vuepress/**',
      ],
      env: { node: true },
    },
    {
      files: ['nova-components/**/*'],
      globals: {
        Nova: false,
      },
    },
  ],
};

# Unit Testing

Unit testing can be enforced using a pre-push hook to your package.json

    "husky": {
        "hooks": {
            "pre-push": "php artisan test"
        }
    },

# PHP Insights

The perfect starting point to analyze the code quality of your PHP projects

# Install

  composer require nunomaduro/phpinsights --dev

# Execute

PHP insights can analyse and fix your php code

  php artisan insights path/to/analyse --fix

# The Full Monty

# package json

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production",
        "prepare": "husky install"
    },
    "devDependencies": {
        "axios": "^0.25",
        "browser-sync": "^2.27.9",
        "browser-sync-webpack-plugin": "^2.3.0",
        "eslint": "^8.15.0",
        "eslint-config-airbnb-base": "^15.0.0",
        "eslint-config-prettier": "^8.5.0",
        "eslint-config-standard": "^17.0.0",
        "eslint-plugin-import": "^2.26.0",
        "eslint-plugin-n": "^15.2.0",
        "eslint-plugin-prettier": "^4.0.0",
        "eslint-plugin-promise": "^6.0.0",
        "eslint-plugin-vue": "^8.7.1",
        "husky": "^8.0.1",
        "laravel-mix": "^6.0.6",
        "lint-staged": "^12.4.1",
        "lodash": "^4.17.19",
        "postcss": "^8.4.14",
        "postcss-html": "^1.4.1",
        "prettier": "^2.6.2",
        "sass": "^1.51.0",
        "sass-loader": "^12.6.0",
        "stylelint": "^14.8.5",
        "stylelint-config-prettier": "^9.0.3",
        "stylelint-config-sass-guidelines": "^9.0.1",
        "stylelint-config-standard-scss": "^3.0.0",
        "stylelint-config-standard-vue": "^1.0.0",
        "stylelint-prettier": "^2.0.0",
        "vue-loader": "^17.0.0"
    },
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged",
            "pre-push": "php artisan test"
        }
    },
    "dependencies": {
        "bootstrap": "^5.1.3",
        "eslint-config-airbnb": "^19.0.4",
        "stylelint-scss": "^4.2.0",
        "video.js": "^7.19.2",
        "vue": "^3.2.33"
    }
}

###lint staged

module.exports = {
  '**/*.php': ['php ./vendor/bin/php-cs-fixer fix --config .php-cs-fixer-config.php --allow-risky=yes'],
  '**/*.php': ['php artisan insights -v'],
  "**/*{js,ts}": "eslint --fix",
  "**/*{vue,htm,html,css,sss,less,scss,sass}": "stylelint --fix"
};