sveltejs / eslint-plugin-svelte

ESLint plugin for Svelte using AST
https://sveltejs.github.io/eslint-plugin-svelte/
MIT License
276 stars 30 forks source link

ESLint Flat config #723

Closed pboling closed 3 months ago

pboling commented 3 months ago

Description

All the docs reference the legacy config style of eslintrc.js, but the new flat config has many advantages, and I'm trying it out to resolve some other issues.

Ref: https://eslint.org/docs/latest/use/configure/configuration-files-new

baseballyama commented 3 months ago

v2.36.0-next.11 is supported flat config.

https://github.com/sveltejs/eslint-plugin-svelte/releases/tag/v2.36.0-next.11

We will remove next version when Svelte 5 becomes RC.

pboling commented 3 months ago

I'm on 2.36.0-next.13, I'm using typescript, and I've followed the basic flat config setup in the readme, and getting:

Argument type
{plugins: {readonly svelte: import("eslint").ESLint.Plugin}, files?: undefined, languageOptions?: undefined, rules?: undefined, processor?: undefined} | {files: string[], languageOptions: {parser: any}, rules: {'no-inner-declarations': string, 'no-self-assign': string, 'svelte/comment-directive': string, 'svelte/system': string}, processor: string, plugins?: undefined} | {rules: {'svelte/comment-directive': string, 'svelte/no-at-debug-tags': string, 'svelte/no-at-html-tags': string, 'svelte/no-dupe-else-if-blocks': string, 'svelte/no-dupe-style-properties': string, 'svelte/no-dynamic-slot-name': string, 'svelte/no-inner-declarations': string, 'svelte/no-not-function-handler': string, 'svelte/no-object-in-text-mustaches': string, 'svelte/no-shorthand-style-property-overrides': string, 'svelte/no-unknown-style-directive-property': string, ...}}
is not assignable to parameter type ConfigWithExtends

My config:

import eslint from '@eslint/js';
import tsESLint from 'typescript-eslint';
import jsdoc from 'eslint-plugin-jsdoc';
import markdown from 'eslint-plugin-markdown';
import eslintPluginSvelte from 'eslint-plugin-svelte';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';

export default tsESLint.config(
    eslint.configs.recommended,
    ...tsESLint.configs.recommended,
    jsdoc.configs['flat/recommended'],
    ...markdown.configs.recommended,
    // flat/prettier: Turns off rules that may conflict with Prettier
    ...eslintPluginSvelte.configs['flat/recommended'],
    eslintPluginPrettierRecommended,
    {
        files: ['**/*.js'],
        plugins: {
            jsdoc,
        },
        rules: {
            'jsdoc/require-description': 'warn'
        }
    },
    {
        languageOptions: {
            ecmaVersion: 2020
        }
    }
);

The problem is the same regardless of whether I use flat/recommended, or flat/prettier.

pboling commented 3 months ago

The core issue I'm having though is an infinite loop when I run this plugin. If I comment out all the other configs, leaving this as the only active plugin, the infinite loop remains.

pboling commented 3 months ago

I've gotten it working, almost perfectly with the new syntax! I'll post the final config here shortly. Also, it may not have been an infinite loop... Flat config doesn't use the .eslintignore file, and I hadn't replicated those settings into glob patterns in the config, so it was legit linting a zillion things.

pboling commented 3 months ago
// pnpm i -D globals
import globals from "globals";

import jsESLint from '@eslint/js';
// import * as espree from "espree";
import tsESLint from 'typescript-eslint';
import tsESLintParser from '@typescript-eslint/parser'
// TODO: I wasn't able to get the parser for extra files working, but maybe we don't need it?
// import * as tsESLintExtraParser from 'typescript-eslint-parser-for-extra-files';
// TODO: Turn on JSDoc, but not yet. Warning volume is already overwhelming.
// import jsdoc from 'eslint-plugin-jsdoc';
import markdown from 'eslint-plugin-markdown';
import eslintPluginSvelte from 'eslint-plugin-svelte';
import svelteESLintParser from 'svelte-eslint-parser';

const ignores = [
    // "./eslint.config.js"
    ".DS_Store",
    "node_modules/**/*",
    "build/**/*",
    ".svelte-kit/**/*",
    "package/**/*",
    ".env",
    ".env.*",
    // Ignore files for PNPM, NPM and YARN
    "pnpm-lock.yaml",
    "package-lock.json",
    "yarn.lock",
    // On CI our PNPM store is local to the application source
    ".pnpm-store/**/*",
    "src/paraglide/**/*",
];
export default tsESLint.config(
    jsESLint.configs.recommended, // Recommended config applied to all files
    ...tsESLint.configs.recommended,

    // jsdoc.configs['flat/recommended'],
    ...markdown.configs.recommended,
    // flat/prettier: Turns off rules that may conflict with Prettier.
    // Prettier is run separately, not through ESLint.
    ...eslintPluginSvelte.configs['flat/prettier'],

    {
        ignores,
        // plugins: {
        //  tsESLint,
        // },
    },
    {
        languageOptions: {
            ecmaVersion: 'latest',
            globals: {
                $bindable: 'readonly',
                ...globals.browser,
                ...globals.node,
                ...globals.es6,
            },
        }
    },
    // {
    //  files: ['**/*.js'],
    // ...ignores,
    //  plugins: {
    //      jsdoc,
    //  },
    //  rules: {
    //      'jsdoc/require-description': 'warn'
    //  }
    // },

    // Configure typescript-eslint-parser for typescript
    {
        files: ['*.ts', '*.tsx'],
        ignores,
        languageOptions: {
            sourceType: "module",
            parser: tsESLintParser,
            // parser: tsESLintExtraParser,
            parserOptions: {
                project: './tsconfig.json',
            },
        },
    },

    // Configure svelte-eslint-parser with typescript-eslint-parser
    //  for the non-svelte parts
    {
        files: ['*.svelte'],
        ignores,
        languageOptions: {
            parser: svelteESLintParser,
            parserOptions: {
                // Parse the `<script>` in `.svelte` as TypeScript by adding the following configuration.
                parser: tsESLintParser,
                extraFileExtensions: ['.svelte'], // This is a required setting in `@typescript-eslint/parser` v4.24.0.
                // parser: {
                //  ts: tsESLintExtraParser,
                //  js: espree,
                // },
                project: './tsconfig.json',
            },
        }
    }
);

Ran out of time to work on this before I got it all working. Still getting Parsing Error: Unexpected token : (I.e. the semicolon is unuexpected) when doing Typescript type casting, so I had to remove all that from my code for now. Aside from that it is working!

pboling commented 3 months ago

Removing the type casting resulted in svelte check errors, so I am still stuck.

polyzen commented 3 months ago

eslint-plugin-svelte can be used in flat configs even without the new flat config support that's only in the next releases: https://github.com/sveltejs/eslint-plugin-svelte/pull/708#issuecomment-2012413054

pboling commented 3 months ago

I'm using it for my config above, or at least I think I am. I am very new to ESLint (& Javascript). In my package.json:

        "eslint-plugin-svelte": "^2.36.0-next.13",

And from above:

    // flat/prettier: Turns off rules that may conflict with Prettier.
    // Prettier is run separately, not through ESLint.
    ...eslintPluginSvelte.configs['flat/prettier'],