Stylelint
How to config Stylelint

How to config Stylelint + Next.js + StyledComponent and not die trying

  1. First of all, we need to install a bunch of dependencies:
yarn add -D stylelint postcss-syntax @stylelint/postcss-css-in-js stylelint-config-recommended stylelint-a11y stylelint-order stylelint-config-rational-order stylelint-config-standard stylelint-config-styled-components
  1. We need to create a .stylelintrc.js and config our rules:
module.exports = {
  customSyntax: '@stylelint/postcss-css-in-js',
  extends: ['stylelint-config-recommended', 'stylelint-a11y/recommended'],
  plugins: [
    'stylelint-a11y',
    'stylelint-order',
    'stylelint-config-rational-order/plugin',
  ],
  rules: {
    'order/properties-order': [],
    'plugin/rational-order': [
      true,
      {
        'border-in-box-model': false,
        'empty-line-between-groups': false,
      },
    ],
    'unit-disallowed-list': [
      ['px'],
      {
        ignoreProperties: {
          px: ['/^border/', 'box-shadow', 'clip'],
        },
        severity: 'warning',
      },
    ],
    'function-no-unknown': null,
    /* Styled components conditional blocks are not supported in css in js stylelint's implementation, and it throws false positives */
    'no-duplicate-selectors': null,
    'no-empty-source': null,
    'no-descending-specificity': null,
  },
};
 
  1. We need to install Stylelint (opens in a new tab) extension for Visual Studio Code and add a custom configuration in .vscode/settings.json. You can find it at Code > Preferences > Settings > Extensions > Stylelint > Edit in settings.json:
  • .vscode/extensions.json
{
  "recommendations": [
    // ...
    "stylelint.vscode-stylelint",
    "dbaeumer.vscode-eslint"
    // ...
  ]
}
  • .vscode/settings.json
{
  "css.validate": false,
  // ...
  "editor.codeActionsOnSave": {
    // ...
    "source.fixAll.stylelint": true
  },
  "less.validate": false,
  "scss.validate": false,
  "stylelint.enable": true,
  "stylelint.packageManager": "yarn",
  "stylelint.validate": [
    "css",
    "postcss",
    "scss",
    "typescript",
    "typescriptreact"
  ],
  // ...
}
  1. Add lint script in your package.json:
{
  // ...
  "scripts: {
    // ...
    "lint:css": "stylelint './src/**/styles.{ts,tsx}'",
    // ...
  }
  // ...
}
  1. (Optional) Add lint script in your .lintstagedrc.js:
'./src/**/styles.{ts,tsx}': 'stylelint --config .stylelintrc.js',
  1. ⚠️ SPOILER: This will be tricky. We need to modify our babel config:
const isDev = process.env.NODE_ENV === "development";
 
let config = {
  presets: ["next/babel"],
  plugins: [
    [
      "styled-components",
      {
        displayName: isDev,
        fileName: isDev,
        meaninglessFileNames: ["index", "styles"],
        minify: !isDev,
        pure: true,
        ssr: true,
      },
    ],
  ],
};
 
// if the process using the babel config is stylelint
// or if the command summons stylelint, remove the babel config
if (
  (process.env._ && process.env._.includes("stylelint")) ||
  process.argv[1].includes("stylelint")
) {
  config = {};
}
 
module.exports = config;
  1. And that's all 🚀