Sarathlal N

Comprehensive Guide to Linting PHP, JavaScript, and CSS in WordPress Plugins Using Composer

Linting is an essential part of modern development practices. It ensures our code adheres to defined standards and avoids common errors. This blog post provides a detailed guide on how to lint PHP, JavaScript, and CSS files in a WordPress plugin using Composer.

Why Linting Matters

For WordPress development, adhering to its coding standards ensures better compatibility, readability, and maintainability.


1. Linting PHP Files

For PHP files, we’ll use PHP_CodeSniffer and the WordPress Coding Standards (WPCS).

Step 1: Install PHP_CodeSniffer and WPCS

In our plugin’s root directory, configure Composer to allow the PHPCS plugin and then install the necessary dependencies:

composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer require --dev wp-coding-standards/wpcs:"^3.0"

Composer will automatically install the project dependencies and register the rulesets from WordPressCS with PHP_CodeSniffer.

Step 2: Verify Installation

Verify that WordPress Coding Standards are registered with PHP_CodeSniffer:

vendor/bin/phpcs -i

We should see a list of installed coding standards, including WordPress.

Step 3: Lint PHP Files

To lint all PHP files in our plugin, run:

vendor/bin/phpcs --standard=WordPress --extensions=php --ignore=vendor,node_modules .

Step 4: Automatically Fix Issues

To fix issues automatically, use PHP Code Beautifier and Fixer (PHPCBF):

vendor/bin/phpcbf --standard=WordPress --extensions=php --ignore=vendor,node_modules .

2. Linting JavaScript Files

For JavaScript files, we’ll use ESLint with the WordPress configuration.

Step 1: Install ESLint and WordPress Configuration

Install ESLint and the WordPress ESLint configuration:

npm install eslint eslint-config-wordpress @eslint/js @eslint/eslintrc --save-dev

Step 2: Create ESLint Configuration File

Create an eslint.config.mjs file in Our plugin’s root directory:

import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
    baseDirectory: __dirname,
    recommendedConfig: js.configs.recommended,
    allConfig: js.configs.all
});

export default [
    {
        ignores: ["**/vendor/", "**/node_modules/"],
    },
    ...compat.extends("wordpress"),
    {
        rules: {
            "no-console": "warn",
            quotes: ["error", "double"],
        },
    },
];

Step 3: Lint JavaScript Files

To lint all JavaScript files, run:

npx eslint "**/admin/js/*.js" "**/public/js/*.js"

Step 4: Automatically Fix Issues

To fix issues automatically:

npx eslint --fix "**/admin/js/*.js" "**/public/js/*.js"

3. Linting CSS Files

For CSS files, we’ll use Stylelint with the WordPress configuration.

Step 1: Install Stylelint and WordPress Configuration

Install Stylelint and the WordPress configuration:

npm install stylelint stylelint-config-wordpress --save-dev

Step 2: Create Stylelint Configuration File

Create a .stylelintrc.json file in our plugin’s root directory:

{
    "extends": "stylelint-config-wordpress",
    "ignoreFiles": ["**/vendor/**", "**/node_modules/**"]
}

Step 3: Lint CSS Files

To lint all CSS files, run:

npx stylelint "**/admin/css/*.css" "**/public/css/*.css"

Step 4: Automatically Fix Issues

To fix issues automatically:

npx stylelint --fix "**/admin/css/*.css" "**/public/css/*.css"

4. Integrating with Composer

To simplify linting and fixing, we can add scripts to our composer.json file:

Add Scripts to composer.json

{
    "scripts": {
        "lint:php": "vendor/bin/phpcs --standard=WordPress --extensions=php --ignore=vendor,node_modules .",
        "fix:php": "vendor/bin/phpcbf --standard=WordPress --extensions=php --ignore=vendor,node_modules .",
        "lint:js": "npx eslint \"**/admin/js/*.js\" \"**/public/js/*.js\"",
        "fix:js": "npx eslint --fix \"**/admin/js/*.js\" \"**/public/js/*.js\"",
        "lint:css": "npx stylelint \"**/admin/css/*.css\" \"**/public/css/*.css\"",
        "fix:css": "npx stylelint --fix \"**/admin/css/*.css\" \"**/public/css/*.css\"",
        "lint": ["@lint:php", "@lint:js", "@lint:css"],
        "fix": ["@fix:php", "@fix:js", "@fix:css"]
    }
}

Here is my final composer.json file.

{
    "require-dev": {
        "wp-coding-standards/wpcs": "^3.0"
    },
    "config": {
        "allow-plugins": {
            "dealerdirect/phpcodesniffer-composer-installer": true
        }
    },
    "scripts": {
        "lint:php": "vendor/bin/phpcs --standard=WordPress --extensions=php --ignore=vendor,node_modules .",
        "fix:php": "vendor/bin/phpcbf --standard=WordPress --extensions=php --ignore=vendor,node_modules .",
        "lint:js": "npx eslint \"**/admin/js/*.js\" \"**/public/js/*.js\"",
        "fix:js": "npx eslint --fix \"**/admin/js/*.js\" \"**/public/js/*.js\"",
        "lint:css": "npx stylelint \"**/admin/css/*.css\" \"**/public/css/*.css\"",
        "fix:css": "npx stylelint --fix \"**/admin/css/*.css\" \"**/public/css/*.css\"",
        "lint": ["@lint:php", "@lint:js", "@lint:css"],
        "fix": ["@fix:php", "@fix:js", "@fix:css"]
    }
}

Usage


5. Optional Enhancements

Pre-commit Hooks with Husky

To ensure code is linted before commits, install Husky:

npm install husky --save-dev
npx husky install
npx husky add .husky/pre-commit "composer run lint"

Continuous Integration

Integrate linting into our CI/CD pipeline using tools like GitHub Actions or GitLab CI/CD.


By setting up PHP_CodeSniffer, ESLint, and Stylelint with Composer, we can create a streamlined workflow for linting and fixing code in our WordPress plugin. This ensures our plugin adheres to WordPress coding standards and maintains high-quality code across all files.

Looking for a skilled WordPress/WooCommerce developer? I'm currently available for freelance, contract, or full-time remote opportunities! Let's create something amazing together. Send me a quick message, and I'll respond within 24 hours!

Recent Posts

  1. Automating Code Linting with GitHub Actions for WordPress Plugins
  2. The Ultimate Guide to Indexing in Database Design
  3. Understanding 'update_meta_cache' in WordPress - When to Use It, When Not to, and Its Impact on Database Queries
  4. A Guide to Configuring JavaScript and SCSS Paths in WordPress Plugins with @wordpress/scripts
  5. Disabling Payment Methods in WooCommerce Based on Conditions

Your Questions / Comments

If you found this article interesting, found errors, or just want to discuss about it, please get in touch.