From 2ccb49f24ba3eb8c6ac79020e203c8d2c581966e Mon Sep 17 00:00:00 2001 From: Janis Hutz Date: Mon, 5 May 2025 15:50:56 +0200 Subject: [PATCH] [Eslint] Finish config --- config/lint/dump | 65 +++++++++++++ config/lint/eslint.config.mjs | 166 ++++++++++++++++++++++------------ scripts/setup-eslint | 2 +- 3 files changed, 176 insertions(+), 57 deletions(-) create mode 100644 config/lint/dump diff --git a/config/lint/dump b/config/lint/dump new file mode 100644 index 0000000..05f1e56 --- /dev/null +++ b/config/lint/dump @@ -0,0 +1,65 @@ +// @ts-check + +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import stylistic from '@stylistic/eslint-plugin'; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + 'plugins': { + '@stylistic/js': stylistic, + '@stylistic/ts': stylistic, + }, + 'rules': { + // Formatting + '@stylistic/js/array-bracket-newline': [ 'error', { 'multiline': true, 'minItems': 4 } ], + '@stylistic/js/array-bracket-spacing': [ 'error', 'always' ], + '@stylistic/js/array-element-newline': [ 'error', { 'multiline': true, 'minItems': 4 } ], + '@stylistic/js/arrow-parens': [ 'error', 'always' ], + '@stylistic/js/arrow-spacing': [ 'error', { 'before': true, 'after': true } ], + '@stylistic/js/block-spacing': [ 'error', 'always' ], + '@stylistic/js/brace-style': [ 'error', '1tbs' ], + '@stylistic/js/comma-spacing': [ 'error', { 'before': false, 'after': true } ], + '@stylistic/js/comma-style': [ 'error', 'last' ], + '@stylistic/js/dot-location': [ 'error', 'property' ], + '@stylistic/js/eol-last': [ 'error', 'always' ], + '@stylistic/js/function-call-spacing': [ 'error', 'never' ], + '@stylistic/js/implicit-arrow-linebreak': [ 'error', 'beside' ], + '@stylistic/js/indent': [ 'error', 4 ], + '@stylistic/js/key-spacing': [ 'error', { 'beforeColon': false, 'afterColon': true } ], + '@stylistic/js/keyword-spacing': [ 'error', { 'before': true, 'after': true } ], + '@stylistic/js/lines-between-class-members': [ 'error', 'always' ], + '@stylistic/js/new-parens': [ 'error', 'always' ], + '@stylistic/js/no-extra-parens': [ 'error', 'all' ], + '@stylistic/js/no-extra-semi': 'error', + '@stylistic/js/no-floating-decimal': 'error', + '@stylistic/js/no-mixed-operators': 'error', + '@stylistic/js/no-mixed-spaces-and-tabs': 'error', + '@stylistic/js/no-multi-spaces': 'error', + '@stylistic/js/no-trailing-spaces': 'error', + '@stylistic/js/no-whitespace-before-property': 'error', + '@stylistic/js/object-curly-newline': [ 'error', { 'multiline': true, 'minProperties': 3 } ], + '@stylistic/js/object-curly-spacing': [ 'error', 'always' ], + '@stylistic/js/one-var-declaration-per-line': 'error', + '@stylistic/js/quote-props': [ 'error', 'always' ], + '@stylistic/js/quotes': [ 'error', 'single' ], + '@stylistic/js/rest-spread-spacing': [ 'error', 'never' ], + '@stylistic/js/semi': [ 'error', 'always' ], + '@stylistic/js/semi-spacing': [ 'error', { 'before': false, 'after': true } ], + '@stylistic/js/semi-style': [ 'error', 'last' ], + '@stylistic/js/space-before-blocks': [ 'error', 'always' ], + '@stylistic/js/space-before-function-paren': [ 'error', 'always' ], + '@stylistic/js/space-in-parens': [ 'error', 'always' ], + '@stylistic/js/space-infix-ops': [ 'error', { 'int32Hint': false } ], + '@stylistic/js/space-unary-ops': 'error', + '@stylistic/js/spaced-comment': [ 'error', 'always' ], + '@stylistic/js/switch-colon-spacing': 'error', + '@stylistic/js/template-curly-spacing': [ 'error', 'always' ], + '@stylistic/js/wrap-iife': [ 'error', 'inside' ], + '@stylistic/js/wrap-regex': 'error', + '@stylistic/ts/type-annotation-spacing': 'error', + } + } +); diff --git a/config/lint/eslint.config.mjs b/config/lint/eslint.config.mjs index 05f1e56..2a181b2 100644 --- a/config/lint/eslint.config.mjs +++ b/config/lint/eslint.config.mjs @@ -1,65 +1,119 @@ -// @ts-check - +import vue from 'eslint-plugin-vue'; import eslint from '@eslint/js'; -import tseslint from 'typescript-eslint'; +import typescript from '@typescript-eslint/eslint-plugin'; import stylistic from '@stylistic/eslint-plugin'; +import parserTs from '@typescript-eslint/parser'; +import tseslint from 'typescript-eslint'; +const style = { + 'plugins': { + '@stylistic': stylistic, + '@stylistic/js': stylistic, + '@stylistic/ts': stylistic, + }, + 'rules': { + // Formatting + '@stylistic/array-bracket-newline': ['error', { 'multiline': true, 'minItems': 4 }], + '@stylistic/array-bracket-spacing': ['error', 'always'], + '@stylistic/array-element-newline': ['error', { 'multiline': true, 'minItems': 4 }], + '@stylistic/arrow-parens': ['error', 'always'], + '@stylistic/arrow-spacing': ['error', { 'before': true, 'after': true }], + '@stylistic/block-spacing': ['error', 'always'], + '@stylistic/brace-style': ['error', '1tbs'], + '@stylistic/comma-spacing': ['error', { 'before': false, 'after': true }], + '@stylistic/comma-style': ['error', 'last'], + '@stylistic/dot-location': ['error', 'property'], + '@stylistic/eol-last': ['error', 'always'], + '@stylistic/function-call-spacing': ['error', 'never'], + '@stylistic/implicit-arrow-linebreak': ['error', 'beside'], + '@stylistic/indent': ['error', 4], + '@stylistic/key-spacing': ['error', { 'beforeColon': false, 'afterColon': true }], + '@stylistic/keyword-spacing': ['error', { 'before': true, 'after': true }], + '@stylistic/lines-between-class-members': ['error', 'always'], + '@stylistic/new-parens': ['error', 'always'], + '@stylistic/no-extra-parens': ['error', 'all'], + '@stylistic/no-extra-semi': 'error', + '@stylistic/no-floating-decimal': 'error', + '@stylistic/no-mixed-operators': 'error', + '@stylistic/no-mixed-spaces-and-tabs': 'error', + '@stylistic/no-multi-spaces': 'error', + '@stylistic/no-trailing-spaces': 'error', + '@stylistic/no-whitespace-before-property': 'error', + '@stylistic/object-curly-newline': ['error', { 'multiline': true, 'minProperties': 3 }], + '@stylistic/object-curly-spacing': ['error', 'always'], + '@stylistic/one-var-declaration-per-line': 'error', + '@stylistic/quote-props': ['error', 'always'], + '@stylistic/quotes': ['error', 'single'], + '@stylistic/rest-spread-spacing': ['error', 'never'], + '@stylistic/semi': ['error', 'always'], + '@stylistic/semi-spacing': ['error', { 'before': false, 'after': true }], + '@stylistic/semi-style': ['error', 'last'], + '@stylistic/space-before-blocks': ['error', 'always'], + '@stylistic/space-before-function-paren': ['error', 'always'], + '@stylistic/space-in-parens': ['error', 'always'], + '@stylistic/space-infix-ops': ['error', { 'int32Hint': false }], + '@stylistic/space-unary-ops': 'error', + '@stylistic/spaced-comment': ['error', 'always'], + '@stylistic/switch-colon-spacing': 'error', + '@stylistic/template-curly-spacing': ['error', 'always'], + '@stylistic/wrap-iife': ['error', 'inside'], + '@stylistic/wrap-regex': 'error', + '@stylistic/ts/type-annotation-spacing': 'error', + } +} + +/** @type {import('eslint').Linter.FlatConfig[]} */ export default tseslint.config( + // Base JavaScript rules eslint.configs.recommended, ...tseslint.configs.recommended, + style, + + // TypeScript support + // { + // files: ['**/*.ts', '**/*.tsx'], + // languageOptions: { + // parser: parserTs, + // parserOptions: { + // ecmaVersion: 'latest', + // sourceType: 'module', + // project: './tsconfig.json', + // ecmaFeatures: { + // jsx: true, + // }, + // }, + // }, + // plugins: { + // '@typescript-eslint': typescript, + // }, + // rules: { + // ...typescript.configs.recommended.rules, + // ...style.rules, + // }, + // }, + + // Vue support (including TS and JSX inside SFCs) { - 'plugins': { - '@stylistic/js': stylistic, - '@stylistic/ts': stylistic, + files: ['**/*.vue'], + extends: [ + 'plugin: vue/recommended' + ], + plugins: { + 'vue-eslint-parser': vue, + '@typescript-eslint': typescript, }, - 'rules': { - // Formatting - '@stylistic/js/array-bracket-newline': [ 'error', { 'multiline': true, 'minItems': 4 } ], - '@stylistic/js/array-bracket-spacing': [ 'error', 'always' ], - '@stylistic/js/array-element-newline': [ 'error', { 'multiline': true, 'minItems': 4 } ], - '@stylistic/js/arrow-parens': [ 'error', 'always' ], - '@stylistic/js/arrow-spacing': [ 'error', { 'before': true, 'after': true } ], - '@stylistic/js/block-spacing': [ 'error', 'always' ], - '@stylistic/js/brace-style': [ 'error', '1tbs' ], - '@stylistic/js/comma-spacing': [ 'error', { 'before': false, 'after': true } ], - '@stylistic/js/comma-style': [ 'error', 'last' ], - '@stylistic/js/dot-location': [ 'error', 'property' ], - '@stylistic/js/eol-last': [ 'error', 'always' ], - '@stylistic/js/function-call-spacing': [ 'error', 'never' ], - '@stylistic/js/implicit-arrow-linebreak': [ 'error', 'beside' ], - '@stylistic/js/indent': [ 'error', 4 ], - '@stylistic/js/key-spacing': [ 'error', { 'beforeColon': false, 'afterColon': true } ], - '@stylistic/js/keyword-spacing': [ 'error', { 'before': true, 'after': true } ], - '@stylistic/js/lines-between-class-members': [ 'error', 'always' ], - '@stylistic/js/new-parens': [ 'error', 'always' ], - '@stylistic/js/no-extra-parens': [ 'error', 'all' ], - '@stylistic/js/no-extra-semi': 'error', - '@stylistic/js/no-floating-decimal': 'error', - '@stylistic/js/no-mixed-operators': 'error', - '@stylistic/js/no-mixed-spaces-and-tabs': 'error', - '@stylistic/js/no-multi-spaces': 'error', - '@stylistic/js/no-trailing-spaces': 'error', - '@stylistic/js/no-whitespace-before-property': 'error', - '@stylistic/js/object-curly-newline': [ 'error', { 'multiline': true, 'minProperties': 3 } ], - '@stylistic/js/object-curly-spacing': [ 'error', 'always' ], - '@stylistic/js/one-var-declaration-per-line': 'error', - '@stylistic/js/quote-props': [ 'error', 'always' ], - '@stylistic/js/quotes': [ 'error', 'single' ], - '@stylistic/js/rest-spread-spacing': [ 'error', 'never' ], - '@stylistic/js/semi': [ 'error', 'always' ], - '@stylistic/js/semi-spacing': [ 'error', { 'before': false, 'after': true } ], - '@stylistic/js/semi-style': [ 'error', 'last' ], - '@stylistic/js/space-before-blocks': [ 'error', 'always' ], - '@stylistic/js/space-before-function-paren': [ 'error', 'always' ], - '@stylistic/js/space-in-parens': [ 'error', 'always' ], - '@stylistic/js/space-infix-ops': [ 'error', { 'int32Hint': false } ], - '@stylistic/js/space-unary-ops': 'error', - '@stylistic/js/spaced-comment': [ 'error', 'always' ], - '@stylistic/js/switch-colon-spacing': 'error', - '@stylistic/js/template-curly-spacing': [ 'error', 'always' ], - '@stylistic/js/wrap-iife': [ 'error', 'inside' ], - '@stylistic/js/wrap-regex': 'error', - '@stylistic/ts/type-annotation-spacing': 'error', - } - } + rules: { + ...typescript.configs.recommended.rules, + ...style.rules, + + // You can override any Vue or TS rules here + 'vue/html-indent': ['error', 4], + 'vue/html-comment-indent': ['error', 4], + 'vue/script-indent': ['error', 4], + 'vue/max-attributes-per-line': ['error', { + singleline: 3, + multiline: { max: 1, allowFirstLine: false }, + }], + }, + }, ); diff --git a/scripts/setup-eslint b/scripts/setup-eslint index 3429a70..b88dce4 100755 --- a/scripts/setup-eslint +++ b/scripts/setup-eslint @@ -5,5 +5,5 @@ SCRIPT_DIR=$(dirname "$0") cp "$SCRIPT_DIR/../config/lint/eslint.config.mjs" . # TODO: Improve eslint config to include JSX and Vue configs too, read on website -npm i --save-dev @eslint/js typescript-eslint @stylistic/eslint-plugin +npm i --save-dev @eslint/js typescript-eslint @stylistic/eslint-plugin eslint-plugin-vue