DEV Community

Tianya School
Tianya School

Posted on

Prettier and ESLint-Automating Code Style and Quality

Prettier and ESLint are complementary tools that together ensure code style consistency and quality. Prettier handles code formatting, while ESLint performs more complex static analysis and rule checking.

Prettier

Purpose

  • Automates code formatting, ensuring consistent indentation, brackets, quotes, and line breaks.
  • Requires minimal configuration, as Prettier has a default code style.
  • Supports multiple programming languages, including JavaScript, TypeScript, CSS, HTML, and more.
  • Can be integrated with ESLint to avoid rule conflicts.

Usage Example

Create a .prettierrc or .prettierrc.json file in the project root to configure Prettier, for example:

{
  "printWidth": 80, // Line width
  "tabWidth": 2, // Tab width
  "useTabs": false, // Use spaces instead of tabs
  "semi": true, // Use semicolons
  "singleQuote": true, // Use single quotes
  "trailingComma": "all", // Trailing commas
  "bracketSpacing": true, // Spaces inside object braces
  "jsxBracketSameLine": false // JSX closing bracket on a new line
}
Enter fullscreen mode Exit fullscreen mode

Install Prettier in your project:

npm install --save-dev prettier
Enter fullscreen mode Exit fullscreen mode

Add Prettier-generated temporary files to .gitignore.

ESLint

Purpose

  • Static code analysis to detect potential errors, code smells, and discouraged programming practices.
  • Offers extensive customizable rules to check code style, variable usage, code complexity, and more.
  • Can be integrated with Prettier to format code first and then perform checks, avoiding format-related issues.

Usage Example

Create an .eslintrc.js or .eslintrc.yaml configuration file:

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    'plugin:react/recommended',
    'airbnb-base',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  plugins: [
    '@typescript-eslint',
    'react',
  ],
  rules: {
    'no-console': 'off', // Disable no-console rule
    'import/no-unresolved': 'error', // Report unresolved imports
  },
};
Enter fullscreen mode Exit fullscreen mode

Install ESLint and related plugins:

npm install --save-dev eslint eslint-plugin-react @typescript-eslint/parser @typescript-eslint/eslint-plugin
Enter fullscreen mode Exit fullscreen mode

Use npx eslint or configure an IDE (e.g., VSCode) with the ESLint plugin for real-time checks.

Integration and Automation

Integrate Prettier with ESLint using eslint-plugin-prettier and eslint-config-prettier:

npm install --save-dev eslint-plugin-prettier eslint-config-prettier
Enter fullscreen mode Exit fullscreen mode

Add the following to .eslintrc.js:

module.exports = {
  // ...
  plugins: ['prettier'],
  extends: ['plugin:prettier/recommended'], // Use Prettier's ESLint rules
  rules: {
    'prettier/prettier': 'error', // Treat Prettier rules as errors
    // ...other rules
  },
};
Enter fullscreen mode Exit fullscreen mode

Now, running eslint --fix will first apply Prettier formatting and then perform ESLint checks.

Example Configuration Files

.prettierrc (Prettier Configuration)

{
  "semi": true,
  "trailingComma": "none",
  "tabWidth": 2,
  "singleQuote": true,
  "printWidth": 120,
  "jsxSingleQuote": true,
  "arrowParens": "avoid",
  "htmlWhitespaceSensitivity": "css",
  "endOfLine": "lf"
}
Enter fullscreen mode Exit fullscreen mode

.eslintrc.js (ESLint Configuration)

module.exports = {
  env: {
    browser: true,
    es6: true,
  },
  extends: [
    'airbnb-base',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
  },
  plugins: ['@typescript-eslint', 'prettier'],
  rules: {
    'prettier/prettier': 'error',
    'no-unused-vars': 'warn',
    'no-console': 'warn',
  },
};
Enter fullscreen mode Exit fullscreen mode

Integration into Build Process

Using Husky and lint-staged for Pre-Commit Checks

Install dependencies:

npm install --save-dev husky lint-staged
Enter fullscreen mode Exit fullscreen mode

Add the following to package.json:

"husky": {
  "hooks": {
    "pre-commit": "lint-staged"
  }
},
"lint-staged": {
  "*.ts?(x)": ["prettier --write", "eslint --fix"],
  "*.js?(x)": ["prettier --write", "eslint --fix"],
  "*.html": ["prettier --write"],
  "*.css": ["prettier --write"]
}
Enter fullscreen mode Exit fullscreen mode

This ensures that lint-staged runs Prettier and ESLint to format and fix code before each commit.

IDE Configuration

In Visual Studio Code, WebStorm, or other IDEs supporting ESLint and Prettier, install the corresponding plugins and configure automatic formatting and linting.

Custom Rules

ESLint's flexibility allows you to create custom rules to meet specific project needs. Add custom rules in .eslintrc.js:

rules: {
  'your-custom-rule': 'error',
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Create a lib or rules directory and define your custom rule modules there.

Common Issues and Solutions

Conflict Resolution

Sometimes, Prettier and ESLint rules may conflict. In such cases, prioritize Prettier's rules for formatting. If specific ESLint rules are needed, disable conflicting Prettier rules in .eslintrc.js:

rules: {
  'prettier/prettier': ['error', { singleQuote: false }] // Disable Prettier's single quote rule
}
Enter fullscreen mode Exit fullscreen mode

Performance Optimization

If ESLint runs slowly, consider these optimizations:

  • Run only when necessary: For example, run only after relevant files are modified.
  • Use the --cache option: ESLint caches checked files to speed up subsequent runs.
  • Use .eslintignore: Exclude files and directories that don’t need checking.

Using ESLint Plugins and Shared Configurations

Plugins

  • @typescript-eslint: Provides additional rules and fixes for TypeScript.
  • eslint-plugin-import: Checks import order and export standards.
  • eslint-plugin-react: Specific rules for React components.
  • eslint-plugin-react-hooks: Checks React Hooks usage.
  • eslint-plugin-prettier: Ensures ESLint works seamlessly with Prettier.

Install these plugins:

npm install --save-dev eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin
Enter fullscreen mode Exit fullscreen mode

Shared Configurations

  • eslint-config-airbnb: Airbnb's coding style guide.
  • eslint-config-prettier: Disables ESLint rules that conflict with Prettier.

Use shared configurations in .eslintrc.js:

module.exports = {
  extends: [
    'airbnb',
    'airbnb-typescript',
    'plugin:@typescript-eslint/recommended',
    'plugin:import/recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'plugin:prettier/recommended',
  ],
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Customizing Shared Configurations

Customize shared configurations based on project needs:

module.exports = {
  extends: [
    'airbnb',
    'airbnb-typescript',
    'plugin:@typescript-eslint/recommended',
    'plugin:import/recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'plugin:prettier/recommended',
  ],
  rules: {
    'import/prefer-default-export': 'off', // Disable warnings for non-default exports
    '@typescript-eslint/explicit-module-boundary-types': 'off', // Disable type declaration warnings
    // Add or modify other rules
  },
};
Enter fullscreen mode Exit fullscreen mode

Advanced Usage

Configuring Environments

Set environment variables in .eslintrc.js to enable rules for specific environments:

env: {
  browser: true,
  es6: true,
  node: true,
  jest: true,
}
Enter fullscreen mode Exit fullscreen mode

Using ESLint’s overrides Field

The overrides field allows you to specify different rules for specific file types or directories. For example, add separate rules for .test.js files:

module.exports = {
  overrides: [
    {
      files: ['**/*.test.js'],
      rules: {
        'no-unused-expressions': 'off', // Disable unused expression warnings in test files
      },
    },
  ],
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Deployment to Continuous Integration (CI)

Integrate ESLint and Prettier into the CI pipeline to ensure all committed code meets standards. For example, configure in GitHub Actions:

name: Lint and Format

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v2
    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '14.x'
    - name: Install dependencies
      run: npm ci
    - name: Lint and format
      run: npm run lint
Enter fullscreen mode Exit fullscreen mode

Top comments (0)