Giter Site home page Giter Site logo

sveltejs / eslint-plugin-svelte Goto Github PK

View Code? Open in Web Editor NEW
255.0 7.0 26.0 2.04 MB

ESLint plugin for Svelte using AST

Home Page: https://sveltejs.github.io/eslint-plugin-svelte/

License: MIT License

JavaScript 4.48% Svelte 5.87% HTML 0.23% TypeScript 88.86% CSS 0.56%
eslint-plugin sveltejs svelte eslint

eslint-plugin-svelte's Introduction

Introduction

eslint-plugin-svelte is the official ESLint plugin for Svelte.
It provides many unique check rules by using the template AST.
You can check on the Online DEMO.

We are working on experimental support for Svelte v5, but may break with new versions of Svelte v5.

NPM license NPM version NPM downloads NPM downloads NPM downloads NPM downloads NPM downloads Build Status

type-coverage Conventional Commits Code Style: Prettier changesets

๐Ÿ“› What is this plugin?

ESLint plugin for Svelte.
It provides many unique check rules using the AST generated by svelte-eslint-parser.

โ— Attention

Cannot be used with eslint-plugin-svelte3

The svelte-eslint-parser and the eslint-plugin-svelte can not be used with the eslint-plugin-svelte3.

Experimental support for Svelte v5

We are working on support for Svelte v5, but it is still an experimental feature. Please note that rules and features related to Svelte v5 may be changed or removed in minor versions without notice.

Migration Guide

To migrate from eslint-plugin-svelte v1, or @ota-meshi/eslint-plugin-svelte, please refer to the migration guide.

๐Ÿ“– Documentation

See documents.

๐Ÿ’ฟ Installation

npm install --save-dev eslint eslint-plugin-svelte svelte

Requirements

  • ESLint v7.0.0 and above
  • Node.js v14.17.x, v16.x and above

๐Ÿ“– Usage

Configuration

New Config (eslint.config.js)

Use eslint.config.js file to configure rules. See also: https://eslint.org/docs/latest/use/configure/configuration-files-new.

Example eslint.config.js:

import eslintPluginSvelte from 'eslint-plugin-svelte';
export default [
  // add more generic rule sets here, such as:
  // js.configs.recommended,
  ...eslintPluginSvelte.configs['flat/recommended'],
  {
    rules: {
      // override/add rules settings here, such as:
      // 'svelte/rule-name': 'error'
    }
  }
];

This plugin provides configs:

  • eslintPluginSvelte.configs['flat/base'] ... Configuration to enable correct Svelte parsing.
  • eslintPluginSvelte.configs['flat/recommended'] ... Above, plus rules to prevent errors or unintended behavior.
  • eslintPluginSvelte.configs['flat/prettier'] ... Turns off rules that may conflict with Prettier (You still need to configure prettier to work with svelte yourself, for example by using prettier-plugin-svelte.).
  • eslintPluginSvelte.configs['flat/all'] ... All rules. This configuration is not recommended for production use because it changes with every minor and major version of eslint-plugin-svelte. Use it at your own risk.

See the rule list to get the rules that this plugin provides.

Legacy Config (.eslintrc)

Use .eslintrc.* file to configure rules. See also: https://eslint.org/docs/user-guide/configuring.

Example .eslintrc.js:

module.exports = {
  extends: [
    // add more generic rule sets here, such as:
    // 'eslint:recommended',
    'plugin:svelte/recommended'
  ],
  rules: {
    // override/add rules settings here, such as:
    // 'svelte/rule-name': 'error'
  }
};

This plugin provides configs:

  • plugin:svelte/base ... Configuration to enable correct Svelte parsing.
  • plugin:svelte/recommended ... Above, plus rules to prevent errors or unintended behavior.
  • plugin:svelte/prettier ... Turns off rules that may conflict with Prettier (You still need to configure prettier to work with svelte yourself, for example by using prettier-plugin-svelte.).
  • plugin:svelte/all ... All rules. This configuration is not recommended for production use because it changes with every minor and major version of eslint-plugin-svelte. Use it at your own risk.

See the rule list to get the rules that this plugin provides.

::: warning โ— Attention

The eslint-plugin-svelte can not be used with the eslint-plugin-svelte3. If you are using eslint-plugin-svelte3 you need to remove it.

  "plugins": [
-   "svelte3"
  ]

:::

Parser Configuration

If you have specified a parser, you need to configure a parser for .svelte.

For example, if you are using the "@babel/eslint-parser", configure it as follows:

module.exports = {
  // ...
  extends: ['plugin:svelte/recommended'],
  // ...
  parser: '@babel/eslint-parser',
  // Add an `overrides` section to add a parser configuration for svelte.
  overrides: [
    {
      files: ['*.svelte'],
      parser: 'svelte-eslint-parser'
    }
    // ...
  ]
  // ...
};

For example, if you are using the "@typescript-eslint/parser", and if you want to use TypeScript in <script> of .svelte, you need to add more parserOptions configuration.

module.exports = {
  // ...
  extends: ['plugin:svelte/recommended'],
  // ...
  parser: '@typescript-eslint/parser',
  parserOptions: {
    // ...
    project: 'path/to/your/tsconfig.json',
    extraFileExtensions: ['.svelte'] // This is a required setting in `@typescript-eslint/parser` v4.24.0.
  },
  overrides: [
    {
      files: ['*.svelte'],
      parser: 'svelte-eslint-parser',
      // Parse the `<script>` in `.svelte` as TypeScript by adding the following configuration.
      parserOptions: {
        parser: '@typescript-eslint/parser'
      }
    }
    // ...
  ]
  // ...
};

If you have a mix of TypeScript and JavaScript in your project, use a multiple parser configuration.

module.exports = {
  // ...
  overrides: [
    {
      files: ['*.svelte'],
      parser: 'svelte-eslint-parser',
      parserOptions: {
        parser: {
          // Specify a parser for each lang.
          ts: '@typescript-eslint/parser',
          js: 'espree',
          typescript: '@typescript-eslint/parser'
        }
      }
    }
    // ...
  ]
  // ...
};

See also https://github.com/sveltejs/svelte-eslint-parser#readme.

::: warning โ— Attention

The TypeScript parser uses a singleton internally and it will only use the options given to it when it was first initialized. If trying to change the options for a different file or override, the parser will simply ignore the new options (which may result in an error). See typescript-eslint/typescript-eslint#6778 for some context.

:::

settings.svelte

You can change the behavior of this plugin with some settings.

e.g.

module.exports = {
  // ...
  settings: {
    svelte: {
      ignoreWarnings: [
        '@typescript-eslint/no-unsafe-assignment',
        '@typescript-eslint/no-unsafe-member-access'
      ],
      compileOptions: {
        postcss: {
          configFilePath: './path/to/my/postcss.config.js'
        }
      },
      kit: {
        files: {
          routes: 'src/routes'
        }
      }
    }
  }
  // ...
};

settings.svelte.ignoreWarnings

Specifies an array of rules that ignore reports in the template.
For example, set rules on the template that cannot avoid false positives.

settings.svelte.compileOptions

Specifies options for Svelte compile. Effects rules that use Svelte compile. The target rules are svelte/valid-compile and svelte/no-unused-svelte-ignore. Note that it has no effect on ESLint's custom parser.

  • postcss ... Specifies options related to PostCSS. You can disable the PostCSS process by specifying false.
    • configFilePath ... Specifies the path of the directory containing the PostCSS configuration.

settings.svelte.kit

If you use SvelteKit with not default configuration, you need to set below configurations. The schema is subset of SvelteKit's configuration. Therefore please check SvelteKit docs for more details.

e.g.

module.exports = {
  // ...
  settings: {
    svelte: {
      kit: {
        files: {
          routes: 'src/routes'
        }
      }
    }
  }
  // ...
};

Running ESLint from the command line

If you want to run eslint from the command line, make sure you include the .svelte extension using the --ext option or a glob pattern, because ESLint targets only .js files by default.

Examples:

eslint --ext .js,.svelte src
eslint "src/**/*.{js,svelte}"

๐Ÿ’ป Editor Integrations

Visual Studio Code

Use the dbaeumer.vscode-eslint extension that Microsoft provides officially.

You have to configure the eslint.validate option of the extension to check .svelte files, because the extension targets only *.js or *.jsx files by default.

Example .vscode/settings.json:

{
  "eslint.validate": ["javascript", "javascriptreact", "svelte"]
}

โœ… Rules

๐Ÿ”ง Indicates that the rule is fixable, and using --fix option on the command line can automatically fix some of the reported problems.
๐Ÿ’ก Indicates that some problems reported by the rule are manually fixable by editor suggestions.
โญ Indicates that the rule is included in the plugin:svelte/recommended config.

Possible Errors

These rules relate to possible syntax or logic errors in Svelte code:

Rule ID Description
svelte/infinite-reactive-loop Svelte runtime prevents calling the same reactive statement twice in a microtask. But between different microtask, it doesn't prevent.
svelte/no-dom-manipulating disallow DOM manipulating
svelte/no-dupe-else-if-blocks disallow duplicate conditions in {#if} / {:else if} chains โญ
svelte/no-dupe-on-directives disallow duplicate on: directives
svelte/no-dupe-style-properties disallow duplicate style properties โญ
svelte/no-dupe-use-directives disallow duplicate use: directives
svelte/no-dynamic-slot-name disallow dynamic slot name โญ๐Ÿ”ง
svelte/no-export-load-in-svelte-module-in-kit-pages disallow exporting load functions in *.svelte module in SvelteKit page components.
svelte/no-not-function-handler disallow use of not function in event handler โญ
svelte/no-object-in-text-mustaches disallow objects in text mustache interpolation โญ
svelte/no-reactive-reassign disallow reassigning reactive values
svelte/no-shorthand-style-property-overrides disallow shorthand style properties that override related longhand properties โญ
svelte/no-store-async disallow using async/await inside svelte stores because it causes issues with the auto-unsubscribing features
svelte/no-unknown-style-directive-property disallow unknown style:property โญ
svelte/require-store-callbacks-use-set-param store callbacks must use set param
svelte/require-store-reactive-access disallow to use of the store itself as an operand. Need to use $ prefix or get function. ๐Ÿ”ง
svelte/valid-compile disallow warnings when compiling. โญ
svelte/valid-prop-names-in-kit-pages disallow props other than data or errors in SvelteKit page components.

Security Vulnerability

These rules relate to security vulnerabilities in Svelte code:

Rule ID Description
svelte/no-at-html-tags disallow use of {@html} to prevent XSS attack โญ
svelte/no-target-blank disallow target="_blank" attribute without rel="noopener noreferrer"

Best Practices

These rules relate to better ways of doing things to help you avoid problems:

Rule ID Description
svelte/block-lang disallows the use of languages other than those specified in the configuration for the lang attribute of <script> and <style> blocks.
svelte/button-has-type disallow usage of button without an explicit type attribute
svelte/no-at-debug-tags disallow the use of {@debug} โญ
svelte/no-ignored-unsubscribe disallow ignoring the unsubscribe method returned by the subscribe() on Svelte stores.
svelte/no-immutable-reactive-statements disallow reactive statements that don't reference reactive values.
svelte/no-inline-styles disallow attributes and directives that produce inline styles
svelte/no-reactive-functions it's not necessary to define functions in reactive statements ๐Ÿ’ก
svelte/no-reactive-literals don't assign literal values in reactive statements ๐Ÿ’ก
svelte/no-unused-class-name disallow the use of a class in the template without a corresponding style
svelte/no-unused-svelte-ignore disallow unused svelte-ignore comments โญ
svelte/no-useless-mustaches disallow unnecessary mustache interpolations ๐Ÿ”ง
svelte/prefer-destructured-store-props destructure values from object stores for better change tracking & fewer redraws ๐Ÿ’ก
svelte/require-each-key require keyed {#each} block
svelte/require-event-dispatcher-types require type parameters for createEventDispatcher
svelte/require-optimized-style-attribute require style attributes that can be optimized
svelte/require-stores-init require initial value in store
svelte/valid-each-key enforce keys to use variables defined in the {#each} block

Stylistic Issues

These rules relate to style guidelines, and are therefore quite subjective:

Rule ID Description
svelte/derived-has-same-inputs-outputs derived store should use same variable names between values and callback
svelte/first-attribute-linebreak enforce the location of first attribute ๐Ÿ”ง
svelte/html-closing-bracket-spacing require or disallow a space before tag's closing brackets ๐Ÿ”ง
svelte/html-quotes enforce quotes style of HTML attributes ๐Ÿ”ง
svelte/html-self-closing enforce self-closing style ๐Ÿ”ง
svelte/indent enforce consistent indentation ๐Ÿ”ง
svelte/max-attributes-per-line enforce the maximum number of attributes per line ๐Ÿ”ง
svelte/mustache-spacing enforce unified spacing in mustache ๐Ÿ”ง
svelte/no-extra-reactive-curlies disallow wrapping single reactive statements in curly braces ๐Ÿ’ก
svelte/no-restricted-html-elements disallow specific HTML elements
svelte/no-spaces-around-equal-signs-in-attribute disallow spaces around equal signs in attribute ๐Ÿ”ง
svelte/prefer-class-directive require class directives instead of ternary expressions ๐Ÿ”ง
svelte/prefer-style-directive require style directives instead of style attribute ๐Ÿ”ง
svelte/shorthand-attribute enforce use of shorthand syntax in attribute ๐Ÿ”ง
svelte/shorthand-directive enforce use of shorthand syntax in directives ๐Ÿ”ง
svelte/sort-attributes enforce order of attributes ๐Ÿ”ง
svelte/spaced-html-comment enforce consistent spacing after the <!-- and before the --> in a HTML comment ๐Ÿ”ง

Extension Rules

These rules extend the rules provided by ESLint itself, or other plugins to work well in Svelte:

Rule ID Description
svelte/no-inner-declarations disallow variable or function declarations in nested blocks โญ
svelte/no-trailing-spaces disallow trailing whitespace at the end of lines ๐Ÿ”ง

SvelteKit

These rules relate to SvelteKit and its best Practices.

Rule ID Description
svelte/no-goto-without-base disallow using goto() without the base path

Experimental

โš ๏ธ These rules are considered experimental and may change or be removed in the future:

Rule ID Description
svelte/experimental-require-slot-types require slot type declaration using the $$Slots interface
svelte/experimental-require-strict-events require the strictEvents attribute on <script> tags

System

These rules relate to this plugin works:

Rule ID Description
svelte/comment-directive support comment-directives in HTML template โญ
svelte/system system rule for working this plugin โญ

Deprecated

  • โš ๏ธ We're going to remove deprecated rules in the next major release. Please migrate to successor/new rules.
  • ๐Ÿ˜‡ We don't fix bugs which are in deprecated rules since we don't have enough resources.
Rule ID Replaced by
svelte/@typescript-eslint/no-unnecessary-condition This rule is no longer needed when using svelte-eslint-parser>=v0.19.0.

๐Ÿป Contributing

Welcome contributing!

Please use GitHub's Issues/PRs.

See also CONTRIBUTING.md

Working With Rules

This plugin uses svelte-eslint-parser for the parser. Check here to find out about AST.

๐Ÿ”’ License

See the LICENSE file for license rights and limitations (MIT).

eslint-plugin-svelte's People

Contributors

baseballyama avatar benmccann avatar detachhead avatar github-actions[bot] avatar jounqin avatar jp-ellis avatar marekdedic avatar marekvospel avatar moufmouf avatar ota-meshi avatar pawelblaszczyk5 avatar ptrxyz avatar renovate-bot avatar renovate[bot] avatar sacrosanctic avatar sdarnell avatar sinonimity avatar tivac avatar uh-zuh avatar xibread avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

eslint-plugin-svelte's Issues

`#await` nested inside an `if` results in "is not defined" errors

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.29.0

What version of eslint-plugin-svelte are you using?

2.14.1

What did you do?

Configuration
module.exports = {
  parser: '@typescript-eslint/parser',
  extends: [
    'eslint:recommended',
    'plugin:svelte/recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking'
  ],
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
    tsconfigRootDir: __dirname,
    project: ['./tsconfig.json'],
    extraFileExtensions: ['.svelte', '.cjs']
  },
  env: {
    es6: true,
    browser: true
  },
  overrides: [
    {
      files: ['*.svelte'],
      parser: 'svelte-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
      },
    }
  ],
  settings: {
    'svelte3/typescript': require('typescript'),
    // ignore style tags in Svelte because of Tailwind CSS
    // See https://github.com/sveltejs/eslint-plugin-svelte3/issues/70
    'svelte3/ignore-styles': () => true
  },
  plugins: ['@typescript-eslint'],
  ignorePatterns: ['node_modules', '.eslintrc.cjs'],
  rules: {
    'indent': ['error', 2],
    'linebreak-style': ['error', 'unix'],
    'quotes': ['error', 'single'],
    'semi': ['error', 'always'],
    'svelte/indent': [
      'error',
      {
        'indent': 2,
        'ignoredNodes': [],
        'switchCase': 1,
        'alignAttributesVertically': false
      },
    ],
    'svelte/button-has-type': 'error',
    'svelte/no-at-debug-tags': 'error',
    'svelte/no-unused-svelte-ignore': 'error',
    '@typescript-eslint/no-unused-vars': ['warn', { 'argsIgnorePattern': "^_" }]
  }
}

<script lang="ts">
  export let message: string|undefined;
  export const formatMessage = async (message: string): Promise<string> => {
    return new Promise(resolve => {
      resolve(message);
    });
  };
</script>

{#if !message}
  No message
{:else}
  {#await formatMessage(message)}
    Loading...
  {:then result}
    {result}
  {/await}
{/if}

What did you expect to happen?

No linting errors should be raised.

What actually happened?

  16:3  error  '$_AwaitThenValue1' is not defined          no-undef
  18:5  error  '$_formatMessage_message_2' is not defined  no-undef

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/binarious/eslint-plugin-svelte-reproduction

https://stackblitz.com/edit/node-s5hzd6?file=src/Reprod.svelte

Additional comments

No response

Add rules to help migrate Svelte Kit (v1.0.0-next.405)

Motivation

Before migrating the Svelte Kit, it might be useful to check the migration requirements in advance and let users know that migration is necessary.

Description

Perhaps we should add some rules.
For example:

  • no-export-load-in-svelte-module-in-kit-pages... Disallow exporting load functions in *.svelte module in Svelte Kit page components.
    See sveltejs/kit#5774 (comment)
  • naming-convention-in-kit-routes ... Require route files follow naming conventions in Svelte Kit routes.
    See sveltejs/kit#5774 (comment)
    Note that essentially, even files under routes can be named freely. It's just not treated as a page. So checking it can be difficult. https://kit.svelte.dev/docs/routing#other-files
    Unable to check if migrated.
  • no-not-data-props-in-kit-pages ... Disallow props other than data in Svelte Kit page components.
    See sveltejs/kit#5774 (comment)

It would be best to be able to automatically locate the svelte.config file if possible, read it, and locate the routes directory. If that's difficult, we'll have to ask the user to configure it with overrides in the eslint configuration.

If you have any other rules you need to migrate or ideas for rules that ESLint can check, please let me know.

Examples

<script context="module">
/* eslint svelte/no-export-load-in-svelte-module-in-kit-pages: error */

/* โœ— BAD */
export function load() { /* ... */}
export const load = () => { /* ... */}
</script>
<!-- โœ— BAD -->
<!-- Filename: index.svelte -->
<script>
/* eslint svelte/naming-convention-in-kit-routes: error */
</script>
/* โœ— BAD */
/* Filename: index.js */
/* eslint svelte/naming-convention-in-kit-routes: error */
<!-- โœ“ GOOD -->
<!-- Filename: +page.svelte -->
<script>
/* eslint svelte/naming-convention-in-kit-routes: error */
</script>
/* โœ“ GOOD */
/* Filename: +page.js */
/* eslint svelte/naming-convention-in-kit-routes: error */
<script>
/* eslint svelte/no-not-data-props-in-kit-pages: error */

/* โœ— BAD */
export let foo;

/* โœ“ GOOD */
export let data;
$: ({foo} = data)
</script>

Additional comments

sveltejs/kit#5774

False positives on reactive declarations starting from 2.11.0

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.26.0

What version of eslint-plugin-svelte are you using?

2.11.0

What did you do?

let currentTab:
    | "confirmation"
    | "destination-selection"
    | "done"
    | "introduction"
    | "moving"
    | "source-selection" = "introduction";

$: progress =
    currentTab === "introduction"
      ? 1 / 5
      : currentTab === "source-selection"
      ? 2 / 5
      : currentTab === "destination-selection"
      ? 3 / 5
      : currentTab === "confirmation"
      ? 4 / 5
      : 0;

What did you expect to happen?

No errors

What actually happened?

9:16 error Placing a void expression inside another expression is forbidden. Move it to its own statement instead @typescript-eslint/no-confusing-void-expression
9:16 error Missing return type on function @typescript-eslint/explicit-function-return-type
10:5 error Unreachable code no-unreachable

Link to Minimal Reproducible Example

skaut/shared-drive-mover#1109 - it's not minimal, I can add a minimal repro if this doesn't help...

Additional comments

This only happens on 2.11.0, see skaut/shared-drive-mover#1109

Bug: `<style lang="scss" global>` causing a parsing error

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.24.0

What version of eslint-plugin-svelte are you using?

2.8.0

What did you do?

This is a very peculiar bug, but I'm pretty confident it is a bug.

.eslintrc.json:

{
    "root": true,
    "extends": [
        "eslint:recommended",
        "plugin:svelte/recommended"
    ],
    "env": {
        "browser": true,
        "node": true,
        "es2017": true
    },
    "rules": {
        "quotes": ["error", "single"],
        "svelte/indent": ["error", { "indent": "tab" }]
    }
}

MyComp.svelte:

<script>
let foo = "bar";
</script>

<p>
        <span>Hi</span>
</p>

<style lang="scss" global>
    body {
        &:hover {
            opacity: 0.1;
        }
    }
</style>

What did you expect to happen?

It should report the linting errors in the markup and script sections, as you would expect.

What actually happened?

After running npx eslint src/lib/MyComp.svelte, I get the following output:

/home/arad/other/eslint-plugin-svelte-bug/src/lib/MyComp.svelte
  15:3  error  Parsing error: Identifier is expected

โœ– 1 problem (1 error, 0 warnings)

This is also what appears in the VS Code editor.

The problem seems to be somehow related to the global attribute on the <style> tag, even when I put a space in front of it, it seems like it starts to work as expected, which is really strange:

Link to Minimal Reproducible Example

https://github.com/aradalvand/eslint-plugin-svelte-bug
(I am in Iran where the government has limited Internet access severely so I'm struggling to actually push the repo, you can still reproduce this by creating a new SvelteKit project (npm create svelte@latest) and then adding the two files I provided above, that's it.)

Additional comments

No response

Using @ typescript-eslint and TypeScript in Svelte Files causes Error "Parsing error:'>' expected" in Svelte file

To use TypeScript files in Svelte apps generated from npx degit sveltejs / template, install"@ typescript-eslint / eslint-plugin" and "@ typescript-eslint / parser"and npx eslint src / ** When I typed --ext .ts, .js, .svelte, I got the following error:

$ npx eslint src / ** --ext .ts, .js, .svelte

/svelte-app/src/App.svelte
  1: 8 error Parsing error:'>' expected

โœ– 1 problem (1 error, 0 warnings)

Commenting out "plugin: @typescript-eslint/recommended" and parser: "@typescript-eslint/parser" in .eslintrc.js eliminate the error.
Is there a solution?
The set .eslintrc.js and development environment are as follows.

# .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    "eslint: recommended",
    "plugin: @ota-meshi/svelte/recommended",
    "plugin: @typescript-eslint/recommended",
    "prettier",
  ],,
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: 12,
    sourceType: "module",
  },
  plugins: ["@typescript-eslint"],
  rules: {
    "@ota-meshi / svelte / button-has-type": "error",
  },
};
# My Development Environment
OS: Windows 10 (WSL2 Ubuntu-18.04)
Used Packages:
"@ ota-meshi / eslint-plugin-svelte": "^ 0.0.19"
"@ typescript-eslint / eslint-plugin": "^ 4.24.0",
"@ typescript-eslint / parser": "^ 4.24.0",
"" prettier ":" ^ 2.3.0 ",
"eslint-config-prettier": "^ 8.3.0"

Add attribute sorting rule

Motivation

Attributes on Svelte components and html can get unwieldy and hard to parse if there are too many. This is especially true when there is a lot of directives involved. One of the main thing I appreciate in eslint-plugin-react is their jsx-sort-props rule. It makes even complex components easy to read.

Proposed solution

Add sort-attributes rule to enforce a sort order of attributes. Alphabetical order would probably suffice for most cases however some sort of predefined "natural" order would be best. Here I'm thinking of the in: and out: directive. I think most would keep this two attributes logically together. jsx-sort-props has accumulated a fair amount of these, e.g.: on: event listeners last for Svelte.

A simple alphabetical ordering I usually maintain manually.

<Checkbox
  bind:this={checkbox}
  class="text-md"
  class:blue={isSelected}
  {completed}
  {id}
  in:fly
  on:change={handleChange}
  out:fade
  use:action
  {...$$props}/>

Appreciate any thought on this!

no-unused-vars with varsIgnorePattern always triggering

We have a few places in our codebase where we need to iterate an array-like object ({ length : 5 }) and we don't care about the contents of each index, because there's nothing there. Maybe we just need to draw something 5 times, or need to use the index value to grab something from somewhere else.

The simplest possible version of that looks like this:

{#each { length : 5 } as _}
    <div>thing</div>
{/each}

I've tried to account for using _ as the iteration value I don't care about using no-unused-vars' support for varsIgnorePattern but nothing I've tried has seemed to work, If I use this package I get defined but never used results.

> eslint .

./eslint-plugin-svelte-unused-vars/component.svelte
  1:26  warning  '_' is defined but never used  no-unused-vars

โœ– 1 problem (0 errors, 1 warning)

Here's a repro as a gist:

https://gist.github.com/tivac/7b0623dfd128d0a60c8ce05069f79e86

Is there a different way I should be trying to set this up? I can work around it for now by using <!-- eslint-disable no-unused-vars --> above each {#each}` tag, but it's clunkier than I'd like.

How to specify rules for js and ts components differently?

For example config below:

{
"overrides": [
    {
      "files": ["*.ts", "*.tsx", "*.svelte"],
      "parserOptions": {
        "project": ["**/tsconfig.json"],
        "extraFileExtensions": [".svelte"]
      },
      "rules": {
        "@typescript-eslint/ts-specific-rules": "error"
        
      }
    },
    {
      "files": ["*.svelte"],
      "parser": "svelte-eslint-parser",
      "parserOptions": {
        "parser": {
          "ts": "@typescript-eslint/parser",
          "js": "espree",
          "typescript": "@typescript-eslint/parser"
        }
      },
      "rules": {
        "@ota-meshi/svelte/no-at-html-tags": "off",
        "@ota-meshi/svelte/button-has-type": "warn",
        "@ota-meshi/svelte/no-useless-mustaches": "error",
        "@ota-meshi/svelte/require-optimized-style-attribute": "warn",
        "@ota-meshi/svelte/html-quotes": "error",
        "@ota-meshi/svelte/indent": "error",
        "@ota-meshi/svelte/max-attributes-per-line": [
          "error",
          {
            "multiline": 1,
            "singleline": 5
          }
        ],
        "@ota-meshi/svelte/mustache-spacing": [
          "error",
          {
            "textExpressions": "never",
            "attributesAndProps": "never",
            "directiveExpressions": "never",
            "tags": {
              "openingBrace": "never",
              "closingBrace": "never"
            }
          }
        ],
        "@ota-meshi/svelte/prefer-class-directive": "error",
        "@ota-meshi/svelte/prefer-style-directive": "error",
        "@ota-meshi/svelte/shorthand-attribute": "error",
        "@ota-meshi/svelte/shorthand-directive": "error",
        "@ota-meshi/svelte/spaced-html-comment": "error"
      }
    }
  ]
}

The above works fine for lang="ts" components, but not for normal js components. Since it is still a svelte file, and will inherit all the typescript rules, giving some weird parsing errors etc. also its listing typescript specific rules for non-typescript segments. Hope this all makes sense.

New Rule: `svelte/no-dupe-on-directives` and `svelte/no-dupe-use-directives`

Motivation

We can define any number of on: and use: directives with the same name, but duplicate directives with the exact same name and expression are probably a mistake.
I would like to find it in the new rule.

See also sveltejs/svelte#8048.

Description

The new rule reports on: directives with exactly the same name and expression, and use: directives with exactly the same name and expression.

Examples

<!-- โœ“ GOOD -->
<button on:click on:click={myHandler}  />
<button on:click={foo} on:click={bar}  />
<div use:clickOutside use:clickOutside={param}  />
<div use:clickOutside={foo} use:clickOutside={bar} />

<!-- โœ— BAD -->
<button on:click on:click />
<button on:click={myHandler} on:click={myHandler} />
<div use:clickOutside use:clickOutside  />
<div use:clickOutside={param} use:clickOutside={param}  />

Additional comments

As for on:, maybe some users want to report even if the expression is different. I think we can add an option to the rule in that case.

<!-- maybe BAD? -->
<button on:click={foo} on:click={bar}  />

<!-- GOOD? -->
<script>
function handler(evt) {
  foo(evt);
  bar(evt);
}
</script>
<button on:click={handler} />

`eslint-disable` comments in svelte html don't work with `eslint-plugin-eslint-comments`

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.30.0

What version of eslint-plugin-svelte are you using?

2.14.1

What did you do?

Configuration
module.exports = {
  root: true,
  parser: "@typescript-eslint/parser",
  "extends": ["plugin:svelte/recommended", "plugin:eslint-comments/recommended"],
  plugins: ["@typescript-eslint"],
  ignorePatterns: ["*.cjs"],
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': [ '.ts', '.tsx', '.cts', '.mts' ],
      'espree': [ '.js', 'jsx', '.cjs', '.mjs' ],
    }
  },
  rules: {
    'svelte/html-self-closing':'error',
    'eslint-comments/require-description': 'error'
  },
  overrides: [
    {
      files: ["*.svelte"],
      parser: "svelte-eslint-parser",
      parserOptions: {
        parser: "@typescript-eslint/parser",
      },
    },
  ]
};
<script>
    // error: eslint-comments/require-description
    //eslint-disable-next-line
    console.log(1)
</script>

<!-- no error -->
<!-- eslint-disable-next-line -->
<input value="asdf">

What did you expect to happen?

eslint-comments/require-description error on the html comment

What actually happened?

no error on the html comment

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/DetachHead/eslint-plugin-svelte-issue/tree/d0eb35b9d72cd26928488f7bbe8cb0ee0f0d1222

Additional comments

i'm not sure whether this is an issue with this plugin or eslint-plugin-eslint-comments, so i'm raising it in both projects

mysticatea/eslint-plugin-eslint-comments#74

no-trailing-spaces "ignoreComments: true" displays error in html comments

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.17.0

What version of eslint-plugin-svelte are you using?

2.6.0

What did you do?

Configuration
{
  "extends": ["prettier", "standard"],
  "plugins": ["@typescript-eslint"],
  "parser": "@typescript-eslint/parser",
  "rules": {
    "arrow-parens": ["error", "as-needed"],
    "operator-linebreak": ["error", "before"],
    "no-trailing-spaces": [
      "error",
      {
        "ignoreComments": true
      }
    ]
  },
  "overrides": [
    {
      "files": ["*.svelte"],
      "parser": "svelte-eslint-parser",
      "rules": {
        "import/first": 0,
        "import/no-duplicates": 0,
        "import/no-mutable-exports": 0,
        "import/no-unresolved": 0,
        "import/prefer-default-export": 0,
        "eslint-plugin-html": 0,
        "no-multiple-empty-lines": 0
      }
    }
  ],
  "env": {
    "node": true
  }
}

In my component, I have a code comment with 2 empty spaces at the end if the first line: ...blends in with paragraph in order to support line-breaks when hovering the component and viewing its description.

<!-- @component
  InlineButton - A button that blends in with paragraph  
  styles, but is interactive.
-->
<button>
  <slot />
</button>

What did you expect to happen?

I would hope ESLint would be ok with it, given my config. No errors appear in my .js files.

What actually happened?

Trailing spaces not allowed. eslint(no-trailing-spaces)

Link to Minimal Reproducible Example

https://ota-meshi.github.io/eslint-plugin-svelte/playground/#shortenedhash

In the playground, the no-trailing-spaces rule only has "on" or "off" functionality, without me able to include the "ignoreComments": true config.

Additional comments

I've had good success with this linting tool while programming in Svelte. Thank you for maintaining!

Add migration guide from `eslint-plugin-svelte3`

Description

I think we need to make a guide that way to switch from eslint-plugin-svelte3 to eslint-plugin-svelte at docs.

I think there are only a few steps for migration, but I think this is necessary because more users will migrate in the near future.

Prettier error: `Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?`

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.23.1

What version of eslint-plugin-svelte are you using?

2.8.0

What did you do?

Configuration
module.exports = {
  parserOptions: {
    parser: "@typescript-eslint/parser",
    project: "./tsconfig.json",
    sourceType: "script",
    extraFileExtensions: [".svelte"],
  },
  env: {
    browser: true,
    node: false,
  },
  plugins: ["@typescript-eslint"],
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
    "plugin:svelte/recommended",
    "plugin:prettier/recommended",
    "plugin:svelte/prettier",
  ],
  overrides: [
    {
      files: ["*.svelte"],
      parser: "svelte-eslint-parser",
      parserOptions: {
        parser: "@typescript-eslint/parser",
      },
    },
  ],
};
<h2>
  {$_("steps." + step + ".header")}
</h2>

<script lang="ts">
  import {_} from "svelte-i18n";

  export let step: string;
</script>

<style lang="scss">
  @import "@material/typography/mdc-typography";
</style>

What did you expect to happen?

No prettier error

What actually happened?

I got Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? error from eslint-plugin-prettier

Link to Minimal Reproducible Example

I can't get eslint-plugin-prettier running in your playground. For a (non-minimal) repro, see skaut/shared-drive-mover@563b5a9

Additional comments

No response

Incompatibility with `eslint-plugin-deprecation`

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.26.0

What version of eslint-plugin-svelte are you using?

2.11.0

What did you do?

Configuration
{
  "parser": "svelte-eslint-parser",
  "parserOptions": {
    "extraFileExtensions": [".svelte"]
  },
  "plugins": ["deprecation"],
  "rules": {
    "deprecation/deprecation": "warn"
  }
}
<div {progress} />

What did you expect to happen?

Eslint runs without errors

What actually happened?

Oops! Something went wrong! :(

ESLint: 8.26.0

TypeError: Cannot read properties of undefined (reading 'parent')
Occurred while linting /home/user/project/App.svelte:5
Rule: "deprecation/deprecation"
    at getSymbol (/home/user/project/node_modules/eslint-plugin-deprecation/dist/rules/deprecation.js:184:25)
    at getDeprecation (/home/user/project/node_modules/eslint-plugin-deprecation/dist/rules/deprecation.js:172:20)
    at identifierRule (/home/user/project/node_modules/eslint-plugin-deprecation/dist/rules/deprecation.js:63:29)
    at ruleErrorHandler (/home/user/project/node_modules/eslint/lib/linter/linter.js:1115:28)
    at /home/user/project/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/home/user/project/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/home/user/project/node_modules/eslint/lib/linter/node-event-generator.js:297:26)
    at NodeEventGenerator.applySelectors (/home/user/project/node_modules/eslint/lib/linter/node-event-generator.js:326:22)
    at NodeEventGenerator.enterNode (/home/user/project/node_modules/eslint/lib/linter/node-event-generator.js:340:14)

Link to Minimal Reproducible Example

https://gist.github.com/marekdedic/b5870cec58295f484b699fa6f60e96c7

Additional comments

No response

`prefer-class-directive` should be ignored on a component

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.19.0

What version of eslint-plugin-svelte are you using?

2.1.0

What did you do?

As mentioned in #173 a reminder to fix a similar issue for prefer-class-directive.

What did you expect to happen?

.

What actually happened?

.

Link to Minimal Reproducible Example

.

Additional comments

No response

documentation - can't scroll when cursor is in a svelte codeblock

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

n/a

What version of eslint-plugin-svelte are you using?

n/a

What did you do?

  1. navigate to a page with svelte codeblocks in it, eg. https://ota-meshi.github.io/eslint-plugin-svelte/rules/comment-directive/
  2. position your cursor above a codeblock and scroll:
    image
  3. position your cursor inside a codeblock and scroll:
    image

What did you expect to happen?

scrolling works no matter where the cursor is

What actually happened?

scrolling only works when the cursor is positioned outside of a codeblock

Link to GitHub Repo with Minimal Reproducible Example

n/a

Additional comments

tested on firefox and chrome

Wrong type checking for reactive statments.

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.23.0

What version of eslint-plugin-svelte are you using?

2.7.0

What did you do?

Trying to write reactive statment with strcit typescript rule applied.

What did you expect to happen?

Working eslint code.

What actually happened?

Wrong typescript eslint.

Link to Minimal Reproducible Example

Hope photos will be enought:

image

image

And ofc if i delete the ? i got another error:

image

Additional comments

No response

svelte/Infinite-reactive-loop

Motivation

I saw that one of the Svelte users faced an infinite loop.
https://twitter.com/knaka/status/1588160616300433411?s=20&t=R5g8ssKc6yXRpZ-va-hrWQ

So I would like to detect such situations automatically by ESLint.

Description

Svelte runtime prevents calling the same reactive statement twice in a microtask.
But between different microtask, it doesn't prevent.

https://svelte.dev/repl/f0d31c7d19584c45af19c87ff06c568c?version=3.52.0

I think this rule has a limitation if a reactive statement depends on the store. (Please see store2 example below)
But I believe this rule is helpful for detecting an infinity loop.

Examples

<script>
  import { store1, store2, store3 } from './store.js'
  const Promise2 = Promise
  let a = 0;
  let b = 0;
  let c = 0;
  let d = 0;
  let e = 0;
  let f = 0;
  let g = 0;
  let h = 0;
  let i = 0;

  // โœ— BAD
  $: (async () => {
    await new Promise((resolve) => {
      setTimeout(() => {
        a = a + 1;
      }, 100)
    })
  })();

  $: new Promise((resolve) => {
    setTimeout(() => {
      b = b + 1;
    }, 100)
  })

  $: {
    new Promise((resolve) => {
      setTimeout(() => {
        c = c + 1;
      }, 100)
    })
  }

  $: (() => {
    new Promise((resolve) => {
      setTimeout(() => {
        d = d + 1;
      }, 100)
    })
  })();

  $: new Promise(() => {
    setTimeout(() => {
      e = e + 1;
    }, 100)
  })

  $: new Promise2(() => {
    setTimeout(() => {
      f = f + 1;
    }, 100)
  })

  $: {
    Promise.all([
      new Promise(() => { throw Error('') })
    ]).catch((err) => {
      setTimeout(() => {
        g = g + 1;
      }, 100)
    });
  }

  const funcH = async () => {
    await new Promise((resolve) => {
      setTimeout(() => {
        h = h + 1;
      }, 100)
    })
  }
  $: (async () => { h; await funcH() })();

  $: (async () => {
    await new Promise((resolve) => {
      setTimeout(() => {
        $store1 = $store1 + 1;
      }, 100)
    })
  })();

  // I think it's impossible to check if `funcStore2` defined at different file.
  const funcStore2 = async () => {
    await new Promise((resolve) => {
      setTimeout(() => {
        $store2 = $store2 + 1;
      }, 100)
    })
  }
  $: (async () => { $store2; await funcStore2() })();

  // โœ“ GOOD
  // This doesn't have infinite reactive
  const funcI = async () => {
    await new Promise((resolve) => {
      setTimeout(() => {
        i = i + 1;
      }, 100)
    })
  }
  $: (async () => { await funcI() })();

  const funcStore3 = async () => {
    await new Promise((resolve) => {
      setTimeout(() => {
        $store3 = $store3 + 1;
      }, 100)
    })
  }
  $: (async () => { await funcStore3() })();
</script>

<p>a: {a}</p>
<p>b: {b}</p>
<p>c: {c}</p>
<p>d: {d}</p>
<p>e: {e}</p>
<p>f: {f}</p>
<p>g: {g}</p>
<p>h: {h}</p>
<p>store1: {$store1}</p>
<p>store2: {$store2}</p>
<br />
<p>i: {i}</p>
<p>store3: {$store3}</p>

Additional comments

No response

Porting some svelte rules I've made elsewhere?

Motivation

I've got a collection of custom eslint rules for svelte that I've been iterating on for a while. Now that this package exists (and is excellent!) I'm curious if you'd be interested in PRs to migrate some or all of these rules into this package?

https://github.com/tivac/eslint-plugin-svelte

Description

Examples

Examples for all of the rules are available in the tests folder.

Additional comments

No response

New Rule: `svelte/no-dupe-slot-name` rule

Motivation

I would like a new rule to warn when using the same slot name multiple times.

<ContactCard>
  <span slot="name">
    Foo
  </span>
  <span slot="name">
    Bar
  </span>
</ContactCard>

Description

The same slot name cannot be used multiple times. It gives an error in Svelte's compiler.
If Svelte warns you, you might think you don't need ESLint rule.
I checked it and it seems to be the render (generate) phase that errors out on duplicate slot names. Since the error is not detected at the time of compilation on language server, there is a possibility that we will notice it late.

So I think we need a rule to check for duplicate slot names.

Examples

<!-- โœ“ GOOD -->
<Foo>
  <span></span>
  <span></span>
</Foo>
<Foo>
  <span slot="firstName">John</span>
  <span slot="lastName">Smith</span>
</Foo>
<Foo>
  <span slot="default"></span>
</Foo>

<!-- โœ— BAD -->
<Foo>
  <span></span>
  <span slot="default"></span>
</Foo>
<Foo>
  <span slot="name">John</span>
  <span slot="name">Smith</span>
</Foo>
<Foo>
  text
  <span slot="default"></span>
</Foo>

Additional comments

No response

`valid-prop-names-in-kit-pages` false positive when exporting `trailingSlash` variable

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.28.0

What version of eslint-plugin-svelte are you using?

2.14.0

What did you do?

Configuration
module.exports = {
    rules: {
        'svelte/valid-prop-names-in-kit-pages': 'error'
    }
}
<!-- +page.svelte -->
<script lang="ts">
    export const trailingSlash = 'always'
</script>

What did you expect to happen?

no error, as trailingSlash is valid to export on sveltekit page components. see sveltejs/kit#7719

What actually happened?

> eslint .


C:\projects\project\src\routes\+page.svelte
  10:18  error  disallow props other than data or errors in Svelte Kit page components  svelte/valid-prop-names-in-kit-pages

Link to GitHub Repo with Minimal Reproducible Example

cant be bothered but i'm gonna make a PR fixing it myself anyway

Additional comments

No response

Design adjustment for docs

Now the document site changes background color after scrolling down, this is a bit weird, and maybe a few more design adjustments should do.

Now I have a few ideas, but if you have more ideas, please write comments.

  • Fix background color
  • change header behavior like SvelteKit web site
  • Left side scroll bar's color. (Maybe SvelteKit web site7s color is better?)

Ignore specific warnings of svelte-check

Description

For eslint-plugin-svelte3 there is svelte3/compiler-options or svelte3/ignore-warnings to ignore some specified compiler warnings, for example all the a11y warnings.

For this plugin I can't seem to find something similar. I can disable the valid-compile rule all together, yet that's a bit unspecific. I could try to disable the warning in my svelte.config.js by defining a config.onwarn function but this does not seem to work with vite/kit.

I suggest to provide a way to ignore specific warnings of the svelte compiler, as I think it might be quite handy.

`no-dupe-style-properties` parse error when empty

@ota-meshi/svelte/no-dupe-style-properties throws an error:

TypeError: Cannot read property 'range' of undefined

When the attribute is empty, for example:

<div class="navbar-main" id="main-navbar" style="" >

svelte/no-dom-manipulating

Motivation

Many Svelte users face Uncaught (in promise) TypeError: Cannot read property 'removeChild' of null.

sveltejs/svelte#6037

This is because userland code (or library code) manipulates DOM directly.
Then between the actual DOM and Svelte runtime expected DOM is different and such an error occurs.

Some user wants to use a library that includes DOM manipulation, so I think the Svelte runtime also need to update.
But at the same time, always actual DOM and Svelte expected DOM also should be same as much as possible.
Therefore we should not use DOM manipulating functions.

Description

In general, DOM manipulating should delegate to Svelte runtime. If you manipulate the DOM directly, the Svelte runtime may confuse because there is a difference between the actual DOM and the Svelte runtime's expected DOM.
Therefore this rule reports where you use DOM manipulating function.
We don't recommend but If you intentionally manipulate the DOM, simply you can ignore this ESLint report.

Examples

<script>
  let div;
  let show;
  
  // โœ“ GOOD
  const toggle = show = !show;
  
  // โœ— BAD
  const remove = () => div.remove();
  
</script>

{#if show}
  <div bind:this="{div}">div</div>
{/if}

<button on:click="{() => toggle()}">Click Me (Good)</button>
<button on:click="{() => remove()}">Click Me (Bad)</button>

Additional comments

I think Vue also can face a similar situation but I couldn't find a such rule.
(I tried to run with Vue.js at playground and the situation is the same.)
I would like to know why Vue.js doesn't need to care about it.

How to make eslint-plugin-tailwindcss working with svelte ?

my currently config, but it not work together <>

module.exports = {
    parser: "@typescript-eslint/parser",
    parserOptions: {
        extraFileExtensions: [".svelte"],
    },
    overrides: [
        {
            files: ["*.svelte"],
            parser: "svelte-eslint-parser",
            parserOptions: {
                parser: {
                    ts: "@typescript-eslint/parser",
                    js: "espree",
                    typescript: "@typescript-eslint/parser",
                    html: "tailwindcss-html-parser",
                }
            },
        },
        // ...
    ],
    plugins: [
        "tailwindcss",
    ],
    extends: [
        'eslint:recommended',
        "plugin:import/recommended",
        "plugin:svelte/prettier",
        "plugin:tailwindcss/recommended"
    ],
    rules: {
        "tailwindcss/classnames-order": "warn",
        "tailwindcss/enforces-negative-arbitrary-values": "warn",
        "tailwindcss/enforces-shorthand": "warn",
        "tailwindcss/migration-from-tailwind-2": "warn",
        "tailwindcss/no-arbitrary-value": "off",
        "tailwindcss/no-custom-classname": "warn",
        "tailwindcss/no-contradicting-classname": "error"
    },
    settings: {
        svelte: {
            ignoreWarnings: [
                "@typescript-eslint/no-unsafe-assignment",
                "@typescript-eslint/no-unsafe-member-access",
            ],
            compileOptions: {
                postcss: true
            }
        },
    },
    "env": {
        "es6": true,
        "browser": true,
        "node": false
    },
};

New rule: store callbacks must use set param

Description

Every now and then I forget how to properly use the "callback on subscriber" form of the built-in svelte stores, and end up writing something like this:

const store = writable(false, () => api.getData());

which doesn't work, because it should actually be written like this:

const store = writable(false, (set) => set(api.getData()));

Svelte REPL Example

A rule that ensures any readable or writable stores that use the callback form follow these rules would be great:

  1. Callback must accept a single parameter
  2. Somewhere within the callback function body it should execute that parameter as a function

I don't think we can get too much more descriptive about it, but even just those two checks would save me from debugging my bad stores.

`#each` block with single line comment between function call and a component inside it causes eslint to hang

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.30.0

What version of eslint-plugin-svelte are you using?

2.14.1

What did you do?

Configuration

n/a, see playground link

{#each a(
//
a) as a}
<A/>{/each}

What did you expect to happen?

eslint finishes checking the code in a timely manner

What actually happened?

eslint hangs

Link to GitHub Repo with Minimal Reproducible Example

https://ota-meshi.github.io/eslint-plugin-svelte/playground/#eJyrVkrOT0lVslKqVk5NTM5QSNSIydPXj8lL1FRILFZIrI3Js3HUt6vWB0nWKtUCAGG/Dwg=

Additional comments

  • the playground hangs when it tries to check this code
    image

    when running eslint locally, it hangs forever with no output

  • also related: #327
    the only difference is the number of characters in the comment and the component name. while trying to reduce this to a minimal example, the behavior kept changing depending on how many characters each line had

playground freezes browser

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

n/a

What version of eslint-plugin-svelte are you using?

n/a

What did you do?

navigate to https://ota-meshi.github.io/eslint-plugin-svelte/playground/#eJyrrgUAAXUA+Q==

What did you expect to happen?

it works

What actually happened?

image
image

Link to GitHub Repo with Minimal Reproducible Example

n/a

Additional comments

tested on chrome and firefox on 3 different devices

indent rule requires that <script> elements be indented

This is how I want to write our svelte components:

<script>
const foo = "bar";
</script>

But if I enable the indent rule, it really wants me to do this:

<script>
    const foo = "bar";
</script>

I can disable it using { ignoredNodes : [ "SvelteScriptElement" ] } but it means that none of the indentation for any direct children will be checked, which is kind of a bummer. I'm sure this is a bit annoying of an ask, but would you be open to adding a new option where a user can define the level of indentation they want specifically for <script>s? It could default to 1, so it wouldn't be a breaking change.

If you're open to this proposal I'd be thrilled to figure out how to send a PR for it.

`eslint --fix` incorrectly changes the wrong line on each block with comment on separate line

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.30.0

What version of eslint-plugin-svelte are you using?

2.14.1

What did you do?

Configuration
module.exports = {
  root: true,
  parser: "@typescript-eslint/parser",
  plugins: ["@typescript-eslint"],
  ignorePatterns: ["*.cjs"],
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': [ '.ts', '.tsx', '.cts', '.mts' ],
      'espree': [ '.js', 'jsx', '.cjs', '.mjs' ],
    }
  },
  rules: {
    "spaced-comment": "error"
  },
  overrides: [
    {
      files: ["*.svelte"],
      parser: "svelte-eslint-parser",
      parserOptions: {
        parser: "@typescript-eslint/parser",
      },
    },
  ]
};
{#each f(
//asdf
d) as k}<Csdf></Csdf>{/each}
eslint . --fix

What did you expect to happen?

space added on line 2 after the //

What actually happened?

space added on line 1 after the {#, causing a syntax error:

{# each f(
//asdf
d) as k}<Csdf></Csdf>{/each}
> eslint . --fix

C:\projects\asdf\src\main.svelte
  1:2  error  Parsing error: Expected if, each or await

โœ– 1 problem (1 error, 0 warnings)

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/DetachHead/eslint-plugin-svelte-issue/tree/d15d9f053c334ee05eb5b4c5ea161e879cbbf523

also same issue but different rule: https://ota-meshi.github.io/eslint-plugin-svelte/playground/#eJyrVkrOT0lVslKqVk5NTM5QSNOIydPXTyxOSYvJS9FUSCxWyK61cQZy9e2q9UEqapVqAbyyES0=

Additional comments

No response

`prefer-style-directive` should be ignored on a component

Svelte will throw an error Style directives cannot be used on components when it tries to change from style= to style:

For example:

<Component style="display:block"/>

will fix to:

<Component style:display="block"/>

Which will throw an error:

Style directives cannot be used on components

I think this is an obvious issue and doesn't require a reproduction.

"parser.parse is not a function" errors with `eslint-plugin-import`

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.28.0

What version of eslint-plugin-svelte are you using?

2.26.0

What did you do?

Configuration
module.exports = {
  root: true,
  parser: "@typescript-eslint/parser",
  extends: ["plugin:svelte/recommended", "plugin:import/recommended"],
  plugins: ["svelte3", "@typescript-eslint"],
  ignorePatterns: ["*.cjs"],
  overrides: [
    {
      files: ["*.svelte"],
      parser: "svelte-eslint-parser",
      parserOptions: {
        parser: "@typescript-eslint/parser",
      },
    },
  ],
  parserOptions: {
    sourceType: "module",
    ecmaVersion: 2020,
    project: "tsconfig.json",
    extraFileExtensions: [".svelte"],
  },
  env: {
    browser: true,
    es2017: true,
    node: true,
  },
};
<script lang="ts">
    import TopAppBar from '@detachhead/smui-top-app-bar'
</script>

What did you expect to happen?

no errors

What actually happened?

  2:27  error    Parse errors in imported module '@detachhead/smui-top-app-bar': parser.parse is not a function (undefined:undefined)  import/default
  2:27  warning  Parse errors in imported module '@detachhead/smui-top-app-bar': parser.parse is not a function (undefined:undefined)  import/no-named-as-default
  2:27  warning  Parse errors in imported module '@detachhead/smui-top-app-bar': parser.parse is not a function (undefined:undefined)  import/no-named-as-default-member

โœ– 3 problems (1 error, 2 warnings)

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/DetachHead/eslint-plugin-svelte-issue/tree/78a2e35c81dd01b1ccfd01608a83fb67c80920b1

Additional comments

i'm not sure if this is an issue with eslint-plugin-svelte or eslint-plugin-import. however this issue did not occur when i was using eslint-plugin-svelte3 so i'm leaning more towards the former

`$_AwaitThenValue1` is not defined

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

v8.23.0

What version of eslint-plugin-svelte are you using?

2.14.0

What did you do?

Configuration
{
  "parser": "svelte-eslint-parser",
  "parserOptions": {
    "parser": "@typescript-eslint/parser",
    "extraFileExtensions": [".svelte"]
  },
  "rules": {
    "no-undef": "error"
  }
}
<script lang="ts">
  const contentPromise = new Promise();
</script>

{#if false}
{:else if true}
  {#await contentPromise then _}
  {/await}
{/if}

What did you expect to happen?

Either no error, or an error message that I can understand

What actually happened?

/home/marekdedic/eslint-svelte-repro/Error.svelte
  8:3  error  '$_AwaitThenValue1' is not defined  no-undef

โœ– 1 problem (1 error, 0 warnings)

Link to GitHub Repo with Minimal Reproducible Example

https://gist.github.com/marekdedic/7394ecd403fdcda3c516a7ea76c944be

Additional comments

No response

Type annotations not working in Svelte's HTML template section

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.23.1

What version of eslint-plugin-svelte are you using?

2.8.0

What did you do?

Configuration
module.exports = {
	root: true,
	parser: '@typescript-eslint/parser',
	extends: [
		'eslint:recommended',
		'plugin:@typescript-eslint/recommended',
		'plugin:@typescript-eslint/recommended-requiring-type-checking',
		'plugin:import/recommended',
		'plugin:import/typescript',
		'plugin:svelte/recommended',
		'plugin:svelte/prettier',
		'prettier'
	],
	plugins: ['unused-imports', '@typescript-eslint', 'import'],
	ignorePatterns: ['*.cjs', 'svelte.config.js', 'tailwind.config.cjs', 'postcss.config.cjs'],
	overrides: [
		{
			files: ['*.svelte'],
			parser: 'svelte-eslint-parser',
			parserOptions: {
				parser: '@typescript-eslint/parser'
			}
		}
	],
	settings: {
		'svelte3/typescript': () => require('typescript'),
		'import/resolver': { typescript: {} },
		'import/parsers': { '@typescript-eslint/parser': ['.ts', '.tsx'] }
	},
	parserOptions: {
		sourceType: 'module',
		ecmaVersion: 2020,
		project: ['./tsconfig.json'],
		extraFileExtensions: ['.svelte']
	},
	env: {
		browser: true,
		es2017: true,
		node: true
	},
	rules: {
		'no-unused-vars': 'off',
		'@typescript-eslint/no-unused-vars': 'off',
		'unused-imports/no-unused-vars': [
			'warn',
			{ vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' }
		],
		'unused-imports/no-unused-imports': 'error'
	}
}

<script lang="ts">
// this works:
const something = (e:any) => e
</script>

<!-- this does not -->
<div on:click={(e : any) => e}>Click</div>

What did you expect to happen?

I expect on:click={(e : any) => e} on the div to work.

What actually happened?

eslint complains that the : would be an unexpected token. As soon as I remove the type annotations, things work great.

Parsing error: Unexpected token (eslint)

Link to Minimal Reproducible Example

EXAMPLE

Additional comments

No response

support for postcss as style lang

Thanks for this parser. It seems to be significantly faster than svelte3 on my setup.

I use postcss-nesting for my setup. While migrating, I am getting error for postcss nesting syntax. Is there a way where I can disable css style checks. In svelte3, I used to ignore styles using following config

settings: {
		 "svelte3/ignore-styles": () => true
},

svelte/require-store-reactive-access

Motivation

This is coming from sveltejs/svelte#7984.

Description

Disallow to render store itself. Need to use $ prefix or get function.

This rule is fixable.

<!-- before -->
<p>{storeValue}</p>
<!-- after -->
<p>{$storeValue}</p>

Examples

<script lang="ts">
  import { writable, get } from 'svelte/store';
  const storeValue = writable("hello");
</script>

<!-- โœ“ GOOD -->
<p>{$storeValue}</p>
<p>{get(storeValue)}</p>

<!-- โœ— BAD -->
<p>{storeValue}</p>

Additional comments

Svelte can define your own store. So we need to support it at some point. (But I think it's difficult. Is there any way to provide it to TypeScript users?)

https://svelte.dev/docs#component-format-script-4-prefix-stores-with-$-to-access-their-values-store-contract

Disable particular rules for template expressions

Description

Hi,
I'd like to disable some rules for template expressions only - typically rules about typescript. Example:

<button onClick={() => {clicked += 1}}>Increment</button> // HERE

<script lang="ts">
function fn() { // HERE
    return 3;
}
</script>

With my current configuration, I get the error Missing return type on function (@typescript-eslint/explicit-function-return-type) on the two lines marked by comments. This is problematic, because I can't use TS in template expressions and therefore I can't add a return type annotation to the first line of my snippet. However, I would still like to have the rule turned on for the second case, where it correctly reports that I forgot to add the return type annotation.

Currently, I found no way of doing this other than manually ignoring all the "false positives" or getting rid of any non-trivial template expressions - I would like to have a way to say to eslint that the rule @typescript-eslint/explicit-function-return-type should be turned off for all template expressions, however it should still check <script /> blocks.

Wrong conditional checkings

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.23.1

What version of eslint-plugin-svelte are you using?

2.8.0

What did you do?

Simple true/false check.

What did you expect to happen?

No eslitn errors.

What actually happened?

image

Link to Minimal Reproducible Example

https://github.com/mpiorowski/svelte-eslint-bug/blob/main/src/routes/%2Bpage.svelte

Additional comments

Thank You for fixing my previous issue, Your plugin is much better then the native svelte one :)

False positive when accessing custom component props

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.26.0

What version of eslint-plugin-svelte are you using?

2.12.0

What did you do?

Configuration
module.exports = {
    root: true,
    parser: '@typescript-eslint/parser',
    extends: [
        'eslint:recommended',
        'plugin:@typescript-eslint/recommended',
        'plugin:@typescript-eslint/recommended-requiring-type-checking',
        'plugin:svelte/recommended',
    ],
    plugins: ['@typescript-eslint'],
    ignorePatterns: ['*.cjs', 'svelte.config.js'],
    overrides: [
        {
            files: ['*.svelte'],
            parser: 'svelte-eslint-parser',
            parserOptions: {
                parser: {
                    ts: '@typescript-eslint/parser',
                    typescript: '@typescript-eslint/parser',
                },
            },
        },
    ],
    parserOptions: {
        sourceType: 'module',
        ecmaVersion: 2022,
        project: ['./tsconfig.json'],
        extraFileExtensions: ['.svelte'],
    },
    env: {
        browser: true,
        es2017: true,
        node: true,
    },
}

Consider this component:

<script lang="ts">
    // comp.svelte
    export const value1 = 3
    export const api = {
        value2: 3,
        get value3() {
            return 1
        },
    }
</script>

I am importing it here:

<script lang="ts">
    import Comp from '$lib/comp.svelte'

    let x: Comp

    $: if (x) console.log(x.value1, x.api.value2, x.api.value3, x.doesNotExist)
</script>

<Comp bind:this={x} />

When I run pnpm lint, I get an error like this:

/tmp/eslint-test/src/routes/+page.svelte
  6:37  error  Unsafe member access .value2 on an `any` value  @typescript-eslint/no-unsafe-member-access
  6:51  error  Unsafe member access .value3 on an `any` value  @typescript-eslint/no-unsafe-member-access

โœ– 2 problems (2 errors, 0 warnings)

However the api property is actually typed correctly and is not of type any. This is also correctly detected by Typescript, yet ESLint seems to not like it:

image

(Please also note that .doesNotExist does not cause any trouble. No idea why that would be ...)

What did you expect to happen?

I expected ESLint to not throw the error since .api is correctly typed.

What actually happened?

ESLint "thinks" .api is of type any and thus raises an error.

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/ptrxyz/eslint-unsafe-member-example/tree/svelte-eslint-parser

Additional comments

  • This bug also seems to be present when I use eslint-plugin-svelte3.
  • Explicitly typing .api does also no solve this issue.

Not compatible with eslint-plugin-simple-import-sort

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.19.0

What version of eslint-plugin-svelte are you using?

2.2.0

What did you do?

You need a Svelte file with unordered imports in its script component, then execute eslint --fix.

What did you expect to happen?

Would apply the simple-import-sort rules, and sort the imports.

What actually happened?

It reported no errors

Link to Minimal Reproducible Example

// .eslintrc.js
module.exports = {
    extends: "eslint:recommended",
    parser: "@typescript-eslint/parser",
    parserOptions: {
        extraFileExtensions: [".svelte"],
    },
    plugins: [
        "svelte",
        "simple-import-sort",
        "@typescript-eslint",
    ],
    rules: {
        "no-unused-vars": "off",
        "no-undef": "off",
        "no-redeclare": "off",
        "no-inner-declarations": "off",
        "no-self-assign": "off",
    },
    overrides: [
        {
            files: "**/*.svelte",
            parser: "svelte-eslint-parser",
            parserOptions: {
                parser: "@typescript-eslint/parser",
            },
            rules: {
                "simple-import-sort/imports": "warn",
                "simple-import-sort/exports": "warn",
            },
        },
    ],
    env: { browser: true },
    ignorePatterns: ["backend_proto.d.ts", "*.svelte.d.ts"],
    globals: {
        globalThis: false,
        NodeListOf: false,
    },
};

Additional comments

No response

`/**/` comments don't work in template code

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

8.30.0

What version of eslint-plugin-svelte are you using?

2.14.1

What did you do?

Configuration n/a
{foo(/**/)}

What did you expect to happen?

no error, as this is valid javascript

What actually happened?

[2:21]: Parsing error: Unexpected token ;

Link to GitHub Repo with Minimal Reproducible Example

https://ota-meshi.github.io/eslint-plugin-svelte/playground/#eJyrVkrOT0lVslKqTsvP19DX0tLXrFWqBQBPdQaV

Additional comments

related: sveltejs/svelte#7456

however that issue is only for comments outside of the expression (ie. {foo() /**/}). comments inside the expression like {foo(/**/)} work correctly in the svelte compiler

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.