├── .editorconfig ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── nodejs.yml │ └── release.yml ├── .gitignore ├── .npmrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── __tests__ ├── index.test.js └── jest.test.js ├── eslint.config.js ├── index.js ├── jest.js ├── package-lock.json └── package.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_style = tab 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [package.json] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.{md,yml}] 16 | indent_style = space 17 | indent_size = 2 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: '/' 5 | schedule: 6 | interval: monthly 7 | open-pull-requests-limit: 3 8 | versioning-strategy: increase 9 | labels: 10 | - 'pr: dependencies' 11 | groups: 12 | development-dependencies: 13 | dependency-type: 'development' 14 | exclude-patterns: ['eslint', 'eslint-*'] 15 | 16 | - package-ecosystem: github-actions 17 | directory: '/' 18 | schedule: 19 | interval: monthly 20 | open-pull-requests-limit: 3 21 | labels: 22 | - 'pr: dependencies' 23 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | merge_group: 9 | 10 | jobs: 11 | lint: 12 | uses: stylelint/.github/.github/workflows/lint.yml@main 13 | 14 | test: 15 | uses: stylelint/.github/.github/workflows/test.yml@main 16 | with: 17 | node-version: '["lts/*"]' 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: ['**'] 6 | 7 | concurrency: 8 | group: ${{ github.workflow }} 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | release: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: write 16 | timeout-minutes: 10 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | - name: Create release 21 | uses: stylelint/changelog-to-github-release-action@main 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | tag-version-prefix = "" 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 24.0.0 4 | 5 | - Changed: `eslint-plugin-n` config from `flag/recommended-script` to `flag/recommended` for both CommonJS and ES modules. 6 | - Changed: bump `@stylistic/eslint-plugin` from v2 to v4. 7 | - Changed: bump `globals` from v15 to v16. 8 | 9 | ## 23.0.0 10 | 11 | - Removed: Node.js less than 18.18 support 12 | - Removed: ESLint 8.x support 13 | - Added: ESLint 9.x support 14 | 15 | ## 22.0.0 16 | 17 | - Removed: `no-confusing-arrow` because of the deprecation of formatting rules. 18 | - Changed: replace deprecated `padding-line-between-statements` with `@stylistic/js/padding-line-between-statements`. 19 | - Changed: bump `eslint-plugin-jest` from v27 to v28. 20 | - Changed: bump `eslint-plugin-n` from v16 to v17. 21 | - Fixed: missing `funding` field in `package.json`. 22 | 23 | ## 21.0.0 24 | 25 | - Removed: Node.js 16 support. 26 | - Changed: bump `eslint-plugin-regexp` from v1 to v2. 27 | - Changed: `parserOptions.ecmaVersion` from `2021` to `2023`. 28 | 29 | ## 20.0.0 30 | 31 | - Added: `n/prefer-global/process` rule. 32 | 33 | ## 19.1.0 34 | 35 | - Added: rules for ESM files. 36 | 37 | ## 19.0.0 38 | 39 | - Removed: Node.js 14 support. 40 | - Changed: migrate from `eslint-plugin-node` to `eslint-plugin-n`. 41 | - Changed: `parserOptions.ecmaVersion` from `2020` to `2021`. 42 | 43 | Migration note: You may need to rewrite rule names for `eslint-plugin-node` like this: 44 | 45 | ```diff js 46 | -// eslint-disable-next-line node/no-extraneous-import 47 | +// eslint-disable-next-line n/no-extraneous-import 48 | ``` 49 | 50 | See also the [`eslint-plugin-n` document](https://github.com/eslint-community/eslint-plugin-n#readme). 51 | 52 | ## 18.0.0 53 | 54 | - Removed: Jest rules from the default config. 55 | - Changed: `eslint-plugin-jest` to optional peer dependencies. 56 | - Added: Jest only config `"stylelint/jest"`. 57 | - Added: `eslint` to peer dependencies. 58 | 59 | Migration note: if you want to continue Jest rules, you need to: 60 | 61 | - run `npm install eslint-plugin-jest --save-dev` 62 | - add `"stylelint/jest"` to `extends` in your ESlint config like this: 63 | 64 | ```diff json 65 | { 66 | - "extends": ["stylelint"] 67 | + "extends": ["stylelint", "stylelint/jest"] 68 | } 69 | ``` 70 | 71 | ## 17.1.0 72 | 73 | - Changed: `parserOptions.ecmaVersion` from `2019` to `2020`. 74 | 75 | ## 17.0.0 76 | 77 | - Added: `func-names` rule. 78 | 79 | ## 16.0.0 80 | 81 | - Removed: support for Node.js v12 (due to breaking change in `eslint-plugin-jest`). 82 | - Changed: bump `eslint-plugin-jest` from v26 to v27. 83 | 84 | ## 15.1.0 85 | 86 | - Changed: bump `eslint-plugin-jest` from v25 to v26. 87 | 88 | ## 15.0.0 89 | 90 | - Changed: bump `eslint-plugin-jest` from v24 to v25. 91 | - Removed: `eslint-plugin-eslint-comments` plugin. 92 | 93 | ## 14.0.0 94 | 95 | - Added: ESM support. 96 | - Added: `eslint-plugin-regexp` plugin. 97 | - Removed: `eslint-plugin-sort-requires` plugin. 98 | 99 | ## 13.1.1 100 | 101 | - Fixed: `node/no-unsupported-feature` range. 102 | 103 | ## 13.1.0 104 | 105 | - Added: `allow` option to `no-console` rule. 106 | 107 | ## 13.0.0 108 | 109 | - Added: `no-shadow` rule. 110 | 111 | ## 12.1.0 112 | 113 | - Changed: bump `eslint-plugin-jest` from v23 to v24. 114 | 115 | ## 12.0.0 116 | 117 | - Removed: `prefer-const`. 118 | - Changed: `ecmaVersion` to `2019`. 119 | - Changed: `eqeqeq` rule to `smart`. 120 | - Added: new rules. 121 | - Added: `eslint-config-prettier`. 122 | 123 | ## 11.1.0 124 | 125 | - Fixed: add the `no-console` rule that was removed from `eslint/recommended` in ESLint v6. 126 | 127 | ## 11.0.0 128 | 129 | - Added: `eslint-plugin-eslint-comments` ESLint plugin using `eslint-comments/recommended` rules. 130 | 131 | ## 10.0.0 132 | 133 | - Added: `eslint-plugin-jest` ESLint plugin `jest/style` rules. 134 | 135 | ## 9.0.0 136 | 137 | - Added: `jest/no-alias-methods` Jest rule. #56 138 | - Added: `jest/prefer-to-be-null` Jest rule. #56 139 | - Added: `jest/prefer-to-be-undefined` Jest rule. #56 140 | - Added: `jest/prefer-to-contain` Jest rule. #56 141 | - Added: `jest/valid-expect-in-promise` Jest rule. #56 142 | - Added: `padding-line-between-statements` rule. #55 143 | 144 | ## 8.3.0 145 | 146 | - Changed: `eslint-plugin-jest` rules to `error` 147 | 148 | ## 8.2.0 149 | 150 | - Added: `eslint-plugin-jest` ESLint plugin. 151 | 152 | ## 8.1.0 153 | 154 | - Added: `one-var` rule. 155 | 156 | ## 8.0.0 157 | 158 | - Added: `eslint-plugin-node` ESLint plugin using `node/recommended` rules. 159 | 160 | ## 7.0.0 161 | 162 | - Removed: stylistic rules. 163 | - Added: eslint `4.0.0` compatibility. 164 | 165 | ## 6.0.0 166 | 167 | - Added: rules and parse options for `node@4` compatibility. 168 | - Removed: `spaced-comment` rules to support flow. 169 | 170 | ## 5.0.0 171 | 172 | - Added: `padded-blocks` rule. 173 | 174 | ## 4.0.0 175 | 176 | - Added: `no-multi-spaces` rule. 177 | 178 | ## 3.0.0 179 | 180 | - Added: eslint `3.0.0` compatibility. 181 | - Removed: eslint `2.0.0` compatibility. 182 | 183 | ## 2.0.0 184 | 185 | - Added: rules for consistent whitespace. 186 | 187 | ## 1.0.0 188 | 189 | - Added: eslint `2.0` compatibility. 190 | - Removed: eslint `1.0` compatibility. 191 | 192 | ## 0.1.0 193 | 194 | - Initial release. 195 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 - present stylelint 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eslint-config-stylelint 2 | 3 | [![NPM version](https://img.shields.io/npm/v/eslint-config-stylelint.svg)](https://www.npmjs.org/package/eslint-config-stylelint) 4 | [![Build Status](https://github.com/stylelint/eslint-config-stylelint/workflows/CI/badge.svg)](https://github.com/stylelint/eslint-config-stylelint/actions) 5 | 6 | > Stylelint org's shareable config for ESLint. 7 | 8 | For consistent JavaScript across Stylelint's repos. 9 | 10 | ## Installation 11 | 12 | ```console 13 | $ npm install eslint-config-stylelint --save-dev 14 | ``` 15 | 16 | ## Usage 17 | 18 | Add this to your ESLint config: 19 | 20 | ```js 21 | import stylelintConfig from "eslint-config-stylelint"; 22 | 23 | export default [...stylelintConfig]; 24 | ``` 25 | 26 | ### For Jest 27 | 28 | Install the plugin additionally: 29 | 30 | ```console 31 | $ npm install eslint-plugin-jest --save-dev 32 | ``` 33 | 34 | Then, update your config: 35 | 36 | ```js 37 | import stylelintConfig from "eslint-config-stylelint"; 38 | import stylelintJestConfig from "eslint-config-stylelint/jest"; 39 | 40 | export default [...stylelintConfig, ...stylelintJestConfig]; 41 | ``` 42 | 43 | ## [Changelog](CHANGELOG.md) 44 | -------------------------------------------------------------------------------- /__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // eslint-disable-next-line n/no-unsupported-features/node-builtins 4 | const test = require('node:test'); 5 | const assert = require('node:assert/strict'); 6 | 7 | const { ESLint } = require('eslint'); 8 | 9 | const newESLint = () => new ESLint({ fix: true }); 10 | 11 | test('load config in ESLint to validate all rule syntax is correct', async () => { 12 | const results = await newESLint().lintText('var foo\n'); 13 | 14 | assert(results); 15 | }); 16 | 17 | test('padding-line-between-statements', async () => { 18 | const code = ` 19 | const asdf = 'dfsdf'; 20 | function xxcv() { 21 | const sdfsdf = 'sdfsdf'; 22 | return sdfsdf; 23 | } 24 | for (let i = 0; i < 10; i++) { 25 | console.log(i); 26 | } 27 | const asdfsfd = 'sdfsdf'; 28 | if (true) { 29 | console.log('true'); 30 | } 31 | `; 32 | 33 | const results = await newESLint().lintText(code); 34 | 35 | const expected = ` 36 | const asdf = 'dfsdf'; 37 | 38 | function xxcv() { 39 | const sdfsdf = 'sdfsdf'; 40 | 41 | return sdfsdf; 42 | } 43 | 44 | for (let i = 0; i < 10; i++) { 45 | console.log(i); 46 | } 47 | 48 | const asdfsfd = 'sdfsdf'; 49 | 50 | if (true) { 51 | console.log('true'); 52 | } 53 | `; 54 | 55 | assert.equal(results[0].output, expected); 56 | }); 57 | -------------------------------------------------------------------------------- /__tests__/jest.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // eslint-disable-next-line n/no-unsupported-features/node-builtins 4 | const test = require('node:test'); 5 | const assert = require('node:assert/strict'); 6 | 7 | const { ESLint } = require('eslint'); 8 | 9 | const config = require('../jest'); 10 | 11 | test('load jest config in ESLint to validate all rule syntax is correct', async () => { 12 | const baseConfig = [ 13 | ...config, 14 | { 15 | settings: { 16 | jest: { version: 27 }, 17 | }, 18 | }, 19 | ]; 20 | const eslint = new ESLint({ baseConfig }); 21 | const results = await eslint.lintText('test("foo");'); 22 | 23 | assert(results); 24 | assert.equal(results.length, 1); 25 | assert.deepEqual( 26 | results[0].messages.map((m) => m.ruleId), 27 | ['jest/no-disabled-tests', 'jest/expect-expect'], 28 | ); 29 | }); 30 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const config = require('./index.js'); 4 | 5 | module.exports = [ 6 | ...config, 7 | { 8 | // TODO: Keep backward compatibility with CommonJS. We may delete after ESM migration. 9 | languageOptions: { 10 | globals: { 11 | module: true, 12 | require: true, 13 | }, 14 | }, 15 | }, 16 | ]; 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const globals = require('globals'); 4 | const js = require('@eslint/js'); // eslint-disable-line n/no-extraneous-require 5 | const nPlugin = require('eslint-plugin-n'); 6 | const regexpPlugin = require('eslint-plugin-regexp'); 7 | const stylisticPlugin = require('@stylistic/eslint-plugin'); 8 | 9 | module.exports = [ 10 | js.configs.recommended, 11 | nPlugin.configs['flat/recommended'], 12 | regexpPlugin.configs['flat/recommended'], 13 | { 14 | plugins: { 15 | '@stylistic': stylisticPlugin, 16 | }, 17 | languageOptions: { 18 | ecmaVersion: 2023, 19 | sourceType: 'module', 20 | globals: { 21 | ...globals.node, 22 | }, 23 | }, 24 | linterOptions: { 25 | reportUnusedDisableDirectives: 'error', 26 | }, 27 | rules: { 28 | 'array-callback-return': 'error', 29 | 'dot-notation': 'error', 30 | eqeqeq: ['error', 'smart'], 31 | 'func-name-matching': 'error', 32 | 'func-names': ['error', 'as-needed'], 33 | 'guard-for-in': 'error', 34 | 'no-console': [ 35 | 'error', 36 | { 37 | allow: ['warn', 'error'], 38 | }, 39 | ], 40 | 'no-else-return': [ 41 | 'error', 42 | { 43 | allowElseIf: false, 44 | }, 45 | ], 46 | 'no-implicit-coercion': 'error', 47 | 'no-lonely-if': 'error', 48 | 'no-shadow': 'error', 49 | 'no-unneeded-ternary': 'error', 50 | 'no-unused-vars': [ 51 | 'error', 52 | { 53 | ignoreRestSiblings: true, 54 | }, 55 | ], 56 | 'no-use-before-define': ['error', 'nofunc'], 57 | 'no-useless-return': 'error', 58 | 'no-var': 'error', 59 | 'object-shorthand': 'error', 60 | 'one-var': ['error', 'never'], 61 | 'operator-assignment': 'error', 62 | 'prefer-arrow-callback': 'error', 63 | 'prefer-object-spread': 'error', 64 | 'prefer-regex-literals': 'error', 65 | 'prefer-rest-params': 'error', 66 | 'prefer-spread': 'error', 67 | 'prefer-template': 'error', 68 | 'sort-imports': ['error', { allowSeparatedGroups: true }], 69 | 70 | // Migrated from the deprecated built-in 'padding-line-between-statements' 71 | '@stylistic/padding-line-between-statements': [ 72 | 'error', 73 | // Require blank lines after all directive prologues (e. g. 'use strict') 74 | { 75 | blankLine: 'always', 76 | prev: 'directive', 77 | next: '*', 78 | }, 79 | // Disallow blank lines between all directive prologues (e. g. 'use strict') 80 | { 81 | blankLine: 'never', 82 | prev: 'directive', 83 | next: 'directive', 84 | }, 85 | // Require blank lines after every sequence of variable declarations 86 | { 87 | blankLine: 'always', 88 | prev: ['const', 'let', 'var'], 89 | next: '*', 90 | }, 91 | // Blank lines could be between variable declarations 92 | { 93 | blankLine: 'any', 94 | prev: ['const', 'let', 'var'], 95 | next: ['const', 'let', 'var'], 96 | }, 97 | // Require blank lines before all return statements 98 | { 99 | blankLine: 'always', 100 | prev: '*', 101 | next: 'return', 102 | }, 103 | // Require blank lines before and after all following statements 104 | { 105 | blankLine: 'always', 106 | prev: '*', 107 | next: ['for', 'function', 'if', 'switch', 'try'], 108 | }, 109 | { 110 | blankLine: 'always', 111 | prev: ['for', 'function', 'if', 'switch', 'try'], 112 | next: '*', 113 | }, 114 | ], 115 | 116 | // Avoid a global variable unique to Node.js. 117 | 'n/prefer-global/process': ['error', 'never'], 118 | 119 | // Prefer code readability, e.g. `[0-9A-Za-z]`. 120 | 'regexp/prefer-d': 'off', 121 | }, 122 | }, 123 | { 124 | files: ['*.mjs'], 125 | rules: { 126 | 'no-restricted-globals': ['error', 'module', 'require'], 127 | strict: ['error', 'never'], 128 | }, 129 | }, 130 | ]; 131 | -------------------------------------------------------------------------------- /jest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const jest = require('eslint-plugin-jest'); 4 | 5 | module.exports = [jest.configs['flat/recommended'], jest.configs['flat/style']]; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-stylelint", 3 | "version": "24.0.0", 4 | "description": "stylelint org's shareable config for eslint", 5 | "keywords": [ 6 | "eslint", 7 | "eslintconfig" 8 | ], 9 | "repository": "stylelint/eslint-config-stylelint", 10 | "funding": [ 11 | { 12 | "type": "opencollective", 13 | "url": "https://opencollective.com/stylelint" 14 | }, 15 | { 16 | "type": "github", 17 | "url": "https://github.com/sponsors/stylelint" 18 | } 19 | ], 20 | "license": "MIT", 21 | "author": "stylelint", 22 | "exports": { 23 | ".": "./index.js", 24 | "./jest": "./jest.js" 25 | }, 26 | "main": "index.js", 27 | "files": [ 28 | "index.js", 29 | "jest.js" 30 | ], 31 | "scripts": { 32 | "format": "prettier . --write", 33 | "lint": "eslint . && prettier . --check", 34 | "release": "np --no-release-draft", 35 | "test": "node --test", 36 | "watch": "node --test --watch" 37 | }, 38 | "prettier": "@stylelint/prettier-config", 39 | "dependencies": { 40 | "@stylistic/eslint-plugin": "^4.2.0", 41 | "eslint-plugin-n": "^17.18.0", 42 | "eslint-plugin-regexp": "^2.7.0", 43 | "globals": "^16.0.0" 44 | }, 45 | "devDependencies": { 46 | "@stylelint/prettier-config": "^3.0.0", 47 | "eslint": "^9.28.0", 48 | "eslint-plugin-jest": "^28.12.0", 49 | "np": "^10.2.0", 50 | "prettier": "^3.5.3" 51 | }, 52 | "peerDependencies": { 53 | "eslint": ">=9.13.0", 54 | "eslint-plugin-jest": ">=28.8.3" 55 | }, 56 | "peerDependenciesMeta": { 57 | "eslint-plugin-jest": { 58 | "optional": true 59 | } 60 | }, 61 | "engines": { 62 | "node": ">=18.18" 63 | }, 64 | "publishConfig": { 65 | "access": "public" 66 | } 67 | } 68 | --------------------------------------------------------------------------------