Giter Club home page Giter Club logo

svelte-eslint-parser's Introduction

svelte-eslint-parser

Svelte parser for ESLint.
You can check it on Online DEMO.

Note that this parser has 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 Coverage Status

⤴️ Motivation

The svelte-eslint-parser aims to make it easy to create your own ESLint rules for Svelte.

The eslint-plugin-svelte is an ESLint plugin that uses the svelte-eslint-parser. I have already implemented some rules.

ESLint Plugins Using svelte-eslint-parser

ESLint plugin for Svelte.
It provides many unique check rules by using the template AST.

ESLint plugin for internationalization (i18n) with Svelte.
It provides rules to help internationalization your application created with Svelte.

❗ Attention

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

💿 Installation

npm install --save-dev eslint svelte-eslint-parser

📖 Usage

  1. Write parser option into your ESLint Config file.
  2. Use glob patterns or --ext .svelte CLI option.

ESLint Config (eslint.config.js)

import js from "@eslint/js";
import svelteParser from "svelte-eslint-parser";
export default [
  js.configs.recommended,
  {
    files: ["**/*.svelte", "*.svelte"],
    languageOptions: {
      parser: svelteParser,
    },
  },
];

ESLint Config (.eslintrc.*)

{
  "extends": "eslint:recommended",
  "overrides": [
    {
      "files": ["*.svelte"],
      "parser": "svelte-eslint-parser"
    }
  ]
}

CLI

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

🔧 Options

parserOptions has the same properties as what espree, the default parser of ESLint, is supporting. For example:

{
  "parserOptions": {
    "sourceType": "module",
    "ecmaVersion": 2021,
    "ecmaFeatures": {
      "globalReturn": false,
      "impliedStrict": false,
      "jsx": false
    }
  }
}

parserOptions.parser

You can use parserOptions.parser property to specify a custom parser to parse <script> tags. Other properties than parser would be given to the specified parser.

For example in eslint.config.js:

import tsParser from "@typescript-eslint/parser";
export default [
  {
    files: ["**/*.svelte", "*.svelte"],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        parser: tsParser,
      },
    },
  },
];

For example in .eslintrc.*:

{
  "parser": "svelte-eslint-parser",
  "parserOptions": {
    "parser": "@typescript-eslint/parser"
  }
}

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.

For example in eslint.config.js:

import tsParser from "@typescript-eslint/parser";
export default [
  // ...
  {
    // ...
    languageOptions: {
      parser: tsParser,
      parserOptions: {
        // ...
        project: "path/to/your/tsconfig.json",
        extraFileExtensions: [".svelte"], // This is a required setting in `@typescript-eslint/parser` v4.24.0.
      },
    },
  },
  {
    files: ["**/*.svelte", "*.svelte"],
    languageOptions: {
      parser: svelteParser,
      // Parse the `<script>` in `.svelte` as TypeScript by adding the following configuration.
      parserOptions: {
        parser: tsParser,
      },
    },
    // ...
  },
];

For example in .eslintrc.*:

module.exports = {
  // ...
  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",
      },
    },
    // ...
  ],
  // ...
};

Multiple parsers

If you want to switch the parser for each lang, specify the object.

For example in eslint.config.js:

import tsParser from "@typescript-eslint/parser";
import espree from "espree";
export default [
  {
    files: ["**/*.svelte", "*.svelte"],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        parser: {
          ts: tsParser,
          js: espree,
          typescript: tsParser,
        },
      },
    },
  },
];

For example in .eslintrc.*:

{
  "parser": "svelte-eslint-parser",
  "parserOptions": {
    "parser": {
      "ts": "@typescript-eslint/parser",
      "js": "espree",
      "typescript": "@typescript-eslint/parser"
    }
  }
}

parserOptions.svelteConfig

If you are using eslint.config.js, you can provide a svelte.config.js in the parserOptions.svelteConfig property.

For example:

import svelteConfig from "./svelte.config.js";
export default [
  {
    files: ["**/*.svelte", "*.svelte"],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        svelteConfig: svelteConfig,
      },
    },
  },
];

If parserOptions.svelteConfig is not specified, some config will be statically parsed from the svelte.config.js file.

The .eslintrc.* style configuration cannot load svelte.config.js because it cannot use ESM. We recommend using the eslint.config.js style configuration.

parserOptions.svelteFeatures

You can use parserOptions.svelteFeatures property to specify how to parse related to Svelte features.

For example in eslint.config.js:

export default [
  {
    files: ["**/*.svelte", "*.svelte"],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        svelteFeatures: {
          /* -- Experimental Svelte Features -- */
          /* It may be changed or removed in minor versions without notice. */
          // This option is for Svelte 5. The default value is `true`.
          // If `false`, ESLint will not recognize rune symbols.
          // If not configured this option, The parser will try to read the option from `compilerOptions.runes` from `svelte.config.js`.
          // If `parserOptions.svelteConfig` is not specified and the file cannot be parsed by static analysis, it will behave as `true`.
          runes: true,
          /* -- Experimental Svelte Features -- */
          /* It may be changed or removed in minor versions without notice. */
          // Whether to parse the `generics` attribute.
          // See https://github.com/sveltejs/rfcs/pull/38
          experimentalGenerics: false,
        },
      },
    },
  },
];

For example in .eslintrc.*:

{
  "parser": "svelte-eslint-parser",
  "parserOptions": {
    "svelteFeatures": {
      /* -- Experimental Svelte Features -- */
      /* It may be changed or removed in minor versions without notice. */
      // This option is for Svelte 5. The default value is `true`.
      // If `false`, ESLint will not recognize rune symbols.
      // If not configured this option, The parser will try to read the option from `compilerOptions.runes` from `svelte.config.js`.
      // If `parserOptions.svelteConfig` is not specified and the file cannot be parsed by static analysis, it will behave as `true`.
      "runes": true,
      /* -- Experimental Svelte Features -- */
      /* It may be changed or removed in minor versions without notice. */
      // Whether to parse the `generics` attribute.
      // See https://github.com/sveltejs/rfcs/pull/38
      "experimentalGenerics": false,
    },
  },
}

Runes support

This is an experimental feature. It may be changed or removed in minor versions without notice.

If you install Svelte v5 the parser will be able to parse runes, and will also be able to parse *.js and *.ts files. If you don't want to use Runes, you may need to configure. Please read parserOptions.svelteFeatures for more details.

When using this mode in an ESLint configuration, it is recommended to set it per file pattern as below.

For example in eslint.config.js:

import svelteConfig from "./svelte.config.js";
export default [
  {
    files: ["**/*.svelte", "*.svelte"],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        parser: "...",
        svelteConfig,
        /* ... */
      },
    },
  },
  {
    files: ["**/*.svelte.js", "*.svelte.js"],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        svelteConfig,
        /* ... */
      },
    },
  },
  {
    files: ["**/*.svelte.ts", "*.svelte.ts"],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        parser: "...(ts parser)...",
        svelteConfig,
        /* ... */
      },
    },
  },
];

For example in .eslintrc.*:

{
  "overrides": [
    {
      "files": ["*.svelte"],
      "parser": "svelte-eslint-parser",
      "parserOptions": {
        "parser": "...",
        /* ... */
      },
    },
    {
      "files": ["*.svelte.js"],
      "parser": "svelte-eslint-parser",
      "parserOptions": {
        /* ... */
      },
    },
    {
      "files": ["*.svelte.ts"],
      "parser": "svelte-eslint-parser",
      "parserOptions": {
        "parser": "...(ts parser)...",
        /* ... */
      },
    },
  ],
}

💻 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"]
}

Usage for Custom Rules / Plugins

🍻 Contributing

Welcome contributing!

Please use GitHub's Issues/PRs.

See also the documentation for the internal mechanism.

🔒 License

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

svelte-eslint-parser's People

Contributors

baseballyama avatar github-actions[bot] avatar iwanabethatguy avatar jounqin avatar kazupon avatar marekdedic avatar ota-meshi avatar renovate-bot avatar renovate[bot] 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

svelte-eslint-parser's Issues

Support for Svelte v5

  • Returns the same AST as before using the new Svelte parser.
    #421
  • Support for Runes.
    • Add Runes symbol to global variable.
      #425
    • Apply correct type information to $derived.
      #430
    • Make *.svelte.js and *.svelte.ts files parsable.
      #426
    • $effect.root (added in 5.0.0-next.14) #446
    • $inspect (added in 5.0.0-next.16) #446
    • change $inspect API (changed in 5.0.0-next.21) (#467)
    • $state.raw (Finally, it changed to $state.frozen. sveltejs/svelte#9851)
    • $state.frozen #466
    • Change to opt-in to rune analysis.
    • $bindable scope analysis. #527
      See sveltejs/eslint-plugin-svelte#768
    • $effect.active() renamed to $effect.tracking()
  • Support for {#snippet} and {@render} https://svelte-5-preview.vercel.app/docs/snippets
    #431
  • Support for new event-handlers https://svelte-5-preview.vercel.app/docs/event-handlers
    onxxx seems to be the same as the attribute (prop).
    So no work is required with this parser. However, I think some work is needed with the eslint-plugin.
  • Support for type annotation in template.
    (If the expression has type annotations, we should skip the type information that the parser is adding automatically.)
  • Use modern AST. #437
  • Waiting for Svelte v5 GA.

Related to sveltejs/eslint-plugin-svelte#587

Component Argument Expression throws TypeError: Cannot read properties of null (reading 'range')

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.57.0

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

What did you do?

Configuration
{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:svelte/base",
        "plugin:@typescript-eslint/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "overrides": [
        {
            "files": [
                "*.svelte"
            ],
            "parser": "svelte-eslint-parser",
            "parserOptions": {
                "parser": "@typescript-eslint/parser"
            }
        }
    ],
    "plugins": [
        "@typescript-eslint"
    ],
    "rules": {
        "indent": [
            "error",
            4,
            {
                "SwitchCase": 1
            }
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "double"
        ],
        "semi": [
            "error",
            "always"
        ],
        "eol-last": [
            "error",
            "always"
        ]
    }
}
test.svelte
<script lang="ts">
    import Button from "$lib/Button.svelte";
    import { writable } from "svelte/store";

    interface store {
        map: Map<number, string>;
        number: number;
    }
    const test = new Map<number, string>([
        [1, "a"],
        [2, "b"],
        [3, "c"],
    ]);

    const store = writable<store>({
        map: test,
        number: 1,
    });
</script>

<div>
    {#if $store.map.size > 1}
        {#each $store.map as [index, tab]}
            <Button
                active={$store.number === index}>
                {index} {tab}
            </Button>
        {/each}
    {/if}
</div>

Button.svelte

<script lang="ts">
    export let active: boolean = false;
</script>

<button class:active={active}>
    <slot />
</button>

What did you expect to happen?

Nothing. Should work.

What actually happened?

TypeError: Cannot read properties of null (reading 'range')
Occurred while linting C:~snip~\src\test.svelte:1
Rule: "indent"

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/TheOnlyRealKat/svelte-eslint-bug

Additional comments

It worked with 0.33, and breaks with 0.34.0-next.3 or newer
See reproduction repo branches.

If you remove
active={$store.number === index}
from the Button Component it works, so I guess it has something todo with that.

version is not found when using bun package manager

i'm trying svelte 5 right now i'm quite enjoying it so far. i'd like to give it a go with bun on my side hustle but i'm getting error: No version matching ">=0.34.0-next.9 <1.0.0" found for specifier "svelte-eslint-parser" (but package exists) error message when i try to use bun install. since it's pre release version and this things can happen, i just want you to know it.

Parsing fails on script tag when id is empty

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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 and svelte-eslint-parser are you using?

What did you do?

Configuration
<!-- Paste your configuration here -->
<head>
  <slot/>
  <link href="/style.css" rel="stylesheet">
  <script id="">const foo = 'Anything goes here';</script>
</head>

What did you expect to happen?

No error

What actually happened?

Parsing error: </script> attempted to close an element that was not open

Link to Minimal Reproducible Example

Not required

Additional comments

No response

Parse error on certain JSDoc syntax

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.44.0

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

What did you do?

Example repo: https://github.com/molily/jest-test

eslint config: https://github.com/molily/jest-test/blob/main/.eslintrc.cjs
Svelte component: https://github.com/molily/jest-test/blob/main/src/HelloWorld.svelte

The component does something like:

<script>
  import { isString } from "./isString.js";
</script>

<p>{isString(undefined)}</p>

isString looks like this:

/**
 * Returns whether a value is a string.
 *
 * @param {any} value
 * @returns {value is string}
 */
export const isString = (value) =>
  typeof value === 'string'

What did you expect to happen?

eslint runs without parsing error.

What actually happened?

npx eslint src/HelloWorld.svelte returns a parse error:

Error while parsing /Users/molily/projekte/jest-test/src/isString.js
Line 5, column 19: Expected }
`parseForESLint` from parser `/Users/molily/projekte/jest-test/node_modules/svelte-eslint-parser/lib/index.js` is invalid and will just be ignored

The reason for the error is this JSDoc line (which is a TypeScript type annotation):

 * @returns {value is string}

If I remove this line, the parsing error is gone.

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/molily/jest-test

Additional comments

No response

Parsing error: ',' expected

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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 and svelte-eslint-parser are you using?

What did you do?

Updated from [email protected] to [email protected]

What did you expect to happen?

I expected eslint to lint my code like before

What actually happened?

Eslint threw an error in one of components pointing to 614:1044 (component doesn't have that many lines), saying error: Parsing error: ',' expected

Link to Minimal Reproducible Example

Repro link
It must've been some change in 0.18.0 -> 0.18.1, because downgrading to 0.18.0 works just fine

Additional comments

It looks like it happens when a reactive assignment is bound to a property of an object.
Like:

$: object.key = doSomething();

No response

False positive unused import when using stores only in reactive statements

image

The savingStatus store is only used in this one line that starts with $:, and the parser incorrectly marks it as an unused import. Removing the reactive statement and converting it into a function fixes it, but it's not very elegant. I'd love it if the parser could ignore the reactive $: statement when determining unused imports!

image

Doesn't seem to understand destructuring inside a reactive statement

$: ({ foo } = bar);

is totally valid & functional in svelte reactive statements. We use it heavily for pulling single fields off of object stores to limit the amount of redrawing we do.

Here's an example of it running in the svelte REPL:

https://svelte.dev/repl/ccaace4f16ca4ea2a77616192ab99e1a?version=3.48.0

But when I run this parser with the base ESLint no-undef rule applied it yells at me about the destructured variables not existing.

https://ota-meshi.github.io/svelte-eslint-parser/playground/#eJyrVkrOT0lVslKyKU4uyiwosYvJU1BIzs8rLlFISixSsFWoVkjLz1ewUohRAtIxSgq11jF5IDUqVgoaELlaoCqgWk2ghI0+3JSYvGqgZK1SLQADrB+9

image
image

Proposal: parse `<style>` contents using PostCSS

Description

Hi,
as suggested in sveltejs/eslint-plugin-svelte#402, I'd like to add support for rules around styles to eslint-plugin-svelte. However, since I am going to be implementing style parsing to do that, I thought maybe it would be better to provide it as part of svelte-eslint-parser?

I am not sure if there's any way of making this compatible with ESTree, but I'm not sure that is actually necessary or even a good idea. I just think that having an AST for styles may make it easier to create eslint-plugin-svelte rules that work with styles.

script tag inside {@html ``} not parsed

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.56.0

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

2.35.1

What did you do?

Configuration
module.exports = {
	root: true,
	extends: [
		'eslint:recommended',
		'plugin:@typescript-eslint/recommended',
		'plugin:svelte/recommended',
		'prettier'
	],
	parser: '@typescript-eslint/parser',
	plugins: ['@typescript-eslint'],
	parserOptions: {
		sourceType: 'module',
		ecmaVersion: 2020,
		extraFileExtensions: ['.svelte']
	},
	env: {
		browser: true,
		es2020: true,
		node: true
	},
	overrides: [
		{
			files: ['*.svelte'],
			parser: 'svelte-eslint-parser',
			parserOptions: {
				parser: '@typescript-eslint/parser'
			}
		}
	],
	rules: {
		'svelte/no-at-html-tags': 'off'
	}
};

<svelte:head>
	{@html `
	<script>
		(function (w, d, s, l, i) {
			w[l] = w[l] || [];
			w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
			var f = d.getElementsByTagName(s)[0],
				j = d.createElement(s),
				dl = l != 'dataLayer' ? '&l=' + l : '';
			j.async = true;
			j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
			f.parentNode.insertBefore(j, f);
		})(window, document, 'script', 'dataLayer', 'GTM-XXX');
	</script>
	`}
</svelte:head>

What did you expect to happen?

I expect that linter will ignore part inside {@html} block

What actually happened?

\GTM\index.svelte
  13:61  error  Parsing error: The script is unterminated

Link to GitHub Repo with Minimal Reproducible Example

https://stackblitz.com/edit/sveltejs-kit-template-default-zguqat

try to run npm run lint in web console to see expected result

Additional comments

it was working before at svelte 3

Nested nodes with their own scope are not nested inside an each block scope

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.41.0

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

What did you do?

Configuration
-
{#each Array.from({ length: open ? count - 1 : count }, (_, i) => i) as item (item)}
{/each}

What did you expect to happen?

The function scope of the callback of Array.from is a child scope of the each scope.

What actually happened?

The callback scope is a sibling of the each scope (both inside the module scope).

Link to GitHub Repo with Minimal Reproducible Example

Reproducible by pasting the code into the playground (sorry I found no way to get a link with the code and tab already selected).

Additional comments

I did not try to find other svelte constructs where this bug may also happen.

[question] what about @stylistic/eslint-plugin

Hi, I just noticed that eslint had deprecated the stylistic rules from 8.53.0. I have an existing project configured using a previous version, and now I'm trying to migrate to the new suggested package @stylistic/eslint-plugin.
As few changes are needed around the config changes, I'm wondering how the config for svelte and this package could be affected.
Any idea?
Thank you

Configure svelte as an optional peer dependency

Description

Does it make sense to mark svelte as an optional peer dependency as it is for eslint-plugin-svelte?

I have an eslint config that conditionally depends on svelte and its plugins, so in some cases it's not installed. However, I can't seem to suppress pnpm's missing peer deps warning with any configuration on my end.

I assume that pnpm's output indicates that the warning is propagating upwards from svelte-eslint-parser:

 WARN  Issues with peer dependencies found
.
└─┬ @theurgi/eslint-config 1.3.0
  ├── ✕ missing peer svelte@"*"
  └─┬ eslint-plugin-svelte 2.18.0
    ├── ✕ missing peer svelte@^3.37.0
    └─┬ svelte-eslint-parser 0.23.0
      └── ✕ missing peer svelte@^3.37.0
Peer dependencies that should be installed:
  svelte@">=3.37.0 <4.0.0"

In my package: @theurgi/eslint-config, I have svelte set as optional:

"peerDependenciesMeta": {
  "svelte": {
    "optional": true
 },

But this does not silence the warning when using pnpm. Any package that depends on my shareable config inherits this warning.

Interestingly, I get no warning when installing with npm. I haven't tried yarn.

Thank you 🙏

Very slow parsing

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

  • I'm using eslint-plugin-svelte.
    (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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 and svelte-eslint-parser are you using?

latest

What did you do?

I'm using a very minimal configuration, only extending plugin:svelte/base which only contains 2 rules: svelte/comment-directive and svelte/system

I've run a benchmark on a substantially large project with hundreds of svelte files.

% time TIMING=1 eslint --ext .svelte,.js,.ts,.cjs 'src/**/*.svelte'
Rule                     | Time (ms) | Relative
:------------------------|----------:|--------:
svelte/comment-directive |     4.085 |    66.7%
svelte/system            |     2.041 |    33.3%

TIMING=1 eslint --ext .svelte,.js,.ts,.cjs 'src/**/*.svelte'  141.41s user 1.09s system 104% cpu 2:16.41 total

As you can see, those rules only added 6ms, but it took over 140 seconds to parse these files.

What did you expect to happen?

eslint should have finished within 2 seconds

What actually happened?

eslint finished over 140 seconds

Link to Minimal Reproducible Example

Because the project is proprietary, I cannot share it in a reproduction repo. But I'm confident it can be replicable on any large project.

Additional comments

No response

Support Svelte Document

Description

This parser should include support for svelte:document.
Currently, since it is not supported, it logs out the following error.

src\App.svelte
  0:0  error  Parsing error: Unknown type:Document

Narrowing type not work in reactive statements

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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 and svelte-eslint-parser are you using?

What did you do?

Configuration
tsconfig.json
{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "resolveJsonModule": true,
    "baseUrl": ".",
    /**
     * Typecheck JS in `.svelte` and `.js` files by default.
     * Disable checkJs if you'd like to use dynamic types in JS.
     * Note that setting allowJs false does not prevent the use
     * of JS in `.svelte` files.
     */
    "allowJs": true,
    "checkJs": true,
    "isolatedModules": true,
    "strict": true
  },
  "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
.eslintrc.js
module.exports = {
  parser: '@typescript-eslint/parser',
  env: {
    es6: true,
    browser: true,
  },
  parserOptions: {
    tsconfigRootDir: __dirname,
    project: ['./tsconfig.json'],
    extraFileExtensions: ['.svelte'],
    parser: '@typescript-eslint/parser',
  },
  plugins: ['@typescript-eslint', 'import'],
  ignorePatterns: [
    'node_modules',
    '.eslintrc.js',
    '*.config.js',
    '*.config.ts',
  ],
  extends: [
    'eslint:recommended',
    'plugin:svelte/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
  ],
  overrides: [
    {
      files: ['*.svelte'],
      parser: 'svelte-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
      },
    },
  ],
  settings: {
    'import/resolver': {
      typescript: {},
    },
  },
};

<script lang="ts">
import type { EventInfo } from './types'
let info: EventInfo | null = null

const lightFormat = (i: Date | number) => i.toString()

fetch('/fakeurl').then(() => { info = { start_at: 0 } }).catch(console.error)

$: startDate = (info?.start_at ? lightFormat(info.start_at) : null)
const endDate = () => (info?.start_at ? lightFormat(info.start_at) : null)
</script>
 
<input type='text'/>

What did you expect to happen?

No lint error.

What actually happened?

Get Unsafe argument of type anyassigned to a parameter of typenumber | Date``

Link to Minimal Reproducible Example

https://stackblitz.com/edit/vitejs-vite-up2dfg?file=src/App.svelte

Additional comments

only happen when strict: true in tsconfig.json and plugin:@typescript-eslint/recommended-requiring-type-checking in .eslintrc.js

Mustache expressions should be wrapped in template literals for consistency with typescript eslint rules

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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?

0.41.0

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

What did you do?

The following is a major footgun and surface area for bugs.

<script lang="ts">

let obj = { 
  a: bool
}
</script>
<a href="/foo/{obj}">...</a>

Will result in

<a href="/foo/[object Object]">..</a>

Even in situations such as

Hello { obj }

We get

Hello [object Object]

There's exactly zero times that I've desired this behavior & almost always a surface area for bugs when refactoring props, types and etc.

This can quite easily occur throughout projects during refactoring or even just developer oversight. We should prevent this from occurring.

I view this as a quite serious typing issue, with no easy apparent remedies.

What did you expect to happen?

What actually happened?

<script lang="ts">
    const array = [1, 2, 3]
</script>
{#each array as e}
    {e}
{/each}

Gets turned into:

              
    const array = [1, 2, 3]
;function $_render1(){        
                  
Array.from(array).forEach((e) => {
    (ee);
});
}

When it should be

    const array = [1, 2, 3]
;function $_render1(){        
                  
Array.from(array).forEach((e) => {
    (`${ee}`);
});
}

Link to GitHub Repo with Minimal Reproducible Example

NA

Additional comments

No response

Destructured store values are seen as unused/undefined

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.15.10

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

2.2.0

What did you do?

Configuration
"no-undef" : "error",
"svelte/valid-compile" : [ "error", {
	// We do some stuff that goes against web a11y best practices, because
	// we're not a website.
	ignoreWarnings : true,
}],

"svelte/no-unknown-style-directive-property" : [ "warn", {
	// These are special gameface-only properties, and svelte does the
	// right thing with them under the covers so let 'em through
	ignoreProperties : [
		"/\\w+PX$/",
	],
}],

"svelte/html-quotes" : [ "warn", {
	prefer : "double",
}],

"svelte/max-attributes-per-line" : [ "warn", {
	singleline : 3,
}],

"svelte/first-attribute-linebreak" : "warn",
"svelte/mustache-spacing" : "warn",
"svelte/prefer-style-directive" : "warn",
"svelte/no-useless-mustaches" : "warn",
"svelte/require-optimized-style-attribute" : "error",
"svelte/shorthand-attribute" : "warn",
"svelte/shorthand-directive" : "warn",
"svelte/spaced-html-comment" : "warn",
"svelte/no-inner-declarations" : "error",

// Disabled in favor of svelte-specific rule
"indent" : "off",
"svelte/indent" : [ "warn", {
	indent : "tab",
	indentScript : false,
}],
<script>
  import { readable } from "svelte/store";

  const bar = {
    foo : readable("hi"),
  };

  $: ({ foo } = $bar);

  $: baz = $foo;
</script>

{baz};

What did you expect to happen?

The destructured store is valid, and should be understood to be a reference to the non-$ prefixed variable.

What actually happened?

[13:9]: 'foo' is defined but never used. [(no-unused-vars)](https://eslint.org/docs/rules/no-unused-vars)
[15:12]: '$foo' is not defined. [(no-undef)](https://eslint.org/docs/rules/no-undef)

Link to Minimal Reproducible Example

https://ota-meshi.github.io/eslint-plugin-svelte/playground/#eJxFkMFuwyAQRH9linIAyTTu1XVy6qVf0Isv2N5UljBYsEmlWvx7wUlccVnNvNkdsYrBjyQa0b5ojS+yg58J7EHRTo71Yq/fk9PxRpYJWp8718YhTAvnCZjmxQfGikBmNL0lJFyCn9GJe+QY2QfqxHvnCj94Fxm9CThhLQJw8R7Nnpd1BRmJFU7nJ/GMTWNOZe/TMYWbsVJuVFbkh2F6df5HKlXhra5rVQ7y9h47AvE1ONwzgyUT9j3TWPACJVWVIT3qHhrIdWuY8ulcW/0bvfnN2iGbWWuP+6d0bs1WEukPJLxt1A==

Additional comments

Svelte REPL Repro of the code correctly subscribing to the destructured store.

Seems similar in some ways to #172 as well.

bug with several parsers for svelte

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.45.0

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

What did you do?

I try mix of TypeScript and JavaScript in the project, so I configured .eslintrc as described in [https://sveltejs.github.io/eslint-plugin-svelte/user-guide/](url)

"overrides": [
{
"files": ["*.svelte"],
"parser": "svelte-eslint-parser",
"parserOptions": {
"parser": {
"ts": "@typescript-eslint/parser",
"js": "espree"
}
}
}
],

but I got there:

[Error - 12:38:00 PM] Error: Error while loading rule '@typescript-eslint/await-thenable': You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.

Whene I change to this:

"overrides": [
{
"files": ["*.svelte"],
"parser": "svelte-eslint-parser",
"parserOptions": {
"parser": "@typescript-eslint/parser"
}
}
],

error is gone.

What should I change to my settings work?

What did you expect to happen?

working EsLint settings

What actually happened?

[Error - 12:38:00 PM] Error: Error while loading rule '@typescript-eslint/await-thenable': You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/mblandr/test

Additional comments

Dependency Dashboard

This issue provides visibility into Renovate updates and their statuses. Learn more

This repository currently has no open or pending branches.


  • Check this box to trigger a request for Renovate to run again on this repository

Nested snippets cause parsing error

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.56.0

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

What did you do?

Configuration
/** @type { import("eslint").Linter.Config } */
module.exports = {
	root: true,
	extends: [
		'eslint:recommended',
		'plugin:@typescript-eslint/recommended',
		'plugin:svelte/recommended',
		'prettier'
	],
	parser: '@typescript-eslint/parser',
	plugins: ['@typescript-eslint'],
	parserOptions: {
		sourceType: 'module',
		ecmaVersion: 2020,
		extraFileExtensions: ['.svelte']
	},
	env: {
		browser: true,
		es2017: true,
		node: true
	},
	overrides: [
		{
			files: ['*.svelte'],
			parser: 'svelte-eslint-parser',
			parserOptions: {
				parser: '@typescript-eslint/parser'
			}
		}
	]
};

src/lib/foo.svelte

<script>
	const { foo } = $props();
</script>

<div>
	{@render foo()}
</div>

src/page/+page.svelte

<script>
	import Foo from '$lib/foo.svelte';
</script>

{#snippet foo()}
	{#snippet bar()}Bar{/snippet}
	Foo {@render bar()}
{/snippet}

<Foo {foo} />

What did you expect to happen?

No error

What actually happened?

pnpm lint

> [email protected] lint nested-snippet-linter-error
> prettier --check . && eslint .

Checking formatting...
All matched files use Prettier code style!

nested-snippet-linter-error/src/routes/+page.svelte
0:0  error  Parsing error: Cannot read properties of undefined (reading 'length')

✖ 1 problem (1 error, 0 warnings)

 ELIFECYCLE  Command failed with exit code 1.


 However, issue in another project was even more cryptic but I can't recreate in minimal example

...src/routes/+page.svelte
0:0  error  Parsing error: fnDecl.params is not iterable

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/vojtechsimetka/nested-snippet-linter-error

Additional comments

Same happens with eslint@9

Reactive variable doesn't do type inference

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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 and svelte-eslint-parser are you using?

What did you do?

Configuration
module.exports = {
  root: true,
  env: {
    es6: true,
    node: true,
  },
  globals: {
    window: true,
  },
  parser: '@typescript-eslint/parser',
  parserOptions: {
    sourceType: 'module',
    ecmaVersion: 2021,
    tsconfigRootDir: __dirname,
    project: ['./tsconfig.eslint.json'],
    extraFileExtensions: ['.svelte'],
  },
  plugins: ['@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
    'plugin:svelte/recommended',
  ],
  rules: {},
  overrides: [
    // see: https://github.com/typescript-eslint/typescript-eslint/blob/main/docs/linting/TROUBLESHOOTING.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
    {
      files: ['*.ts'],
      rules: {
        'no-undef': 'off',
      },
    },
    {
      files: ['**/*.svelte'],
      parser: 'svelte-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser',
      },
      rules: {
        'no-undef': 'off',
      },
    },
  ],
};

<script lang="ts">
  let obj = {
    child: {
      title: "hello!",
    },
  };

  $: child = obj.child;
  $: title = child?.title ?? "Yo!";
</script>

{child}{title}

What did you expect to happen?

No ESLint error comes.

What actually happened?

/Users/baseballyama/Desktop/git/issue-eslint-plugin-svelte-1/src/Sample.svelte
  9:6   error  Unsafe assignment of an `any` value            @typescript-eslint/no-unsafe-assignment
  9:14  error  Unsafe member access .title on an `any` value  @typescript-eslint/no-unsafe-member-access

✖ 2 problems (2 errors, 0 warnings)

image

Link to Minimal Reproducible Example

https://github.com/baseballyama/issue-eslint-plugin-svelte-1

Additional comments

I think this is because TypeScript AST is inferred to any.
I'll try to fix this, but before that I would confirm how to fix it.
Do we need to type infer by inserting a dummy let child = obj.child; or something else?

False positive TypeScript ESLint errors when using slot props

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.47.0

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

What did you do?

Configuration

module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended-type-checked',
'plugin:svelte/recommended',
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
extraFileExtensions: ['.svelte'],
},
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
},
},
],
root: true,
env: {
browser: true,
node: true,
},
};

// App.svelte
<script lang="ts">
	import CustomList from './lib/CustomList.svelte';
	import type { ListItem } from './lib/types';

	const items: ListItem[] = [
		{
			title: 'Svelte.dev',
			link: 'https://svelte.dev',
		},
		{
			title: 'TypeScript ESLint',
			link: 'https://typescript-eslint.io',
		},
		{
			title: 'TypeScript',
			link: 'https://www.typescriptlang.org',
		},
	];

	const openLink = (item: ListItem) => {
		window.location.replace(item.link);
	};
</script>

<main>
	<CustomList
		{items}
		let:item
	>
		<div>
			{item.title}
			<button
				on:click={() => {
					openLink(item);
				}}>Open Link</button
			>
		</div>
	</CustomList>
</main>


// CustomList.svelte
<script lang="ts">
	import type { ListItem } from './types';

	export let items: ListItem[];
</script>

<div>
	<ul>
		{#each items as item (item.title)}
			<li>
				<slot {item} />
			</li>
		{/each}
	</ul>
</div>
// types.ts
export interface ListItem {
	title: string;
	link: string;
}

What did you expect to happen?

No ESLint errors or warnings are raised for the code, as the types are defined and compatible with how they are being used.

What actually happened?

ESLint raises two errors. The first, @typescript-eslint/no-unsafe-member-access, when accessing the title property of the item slot prop; the second, @typescript-eslint/no-unsafe-argument, passing the item slot prop to the openLink function.

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/rowanlovejoy/eslint-svelte-test

Additional comments

The minimal reproduction repo is based on the Vite Svelte template described here: https://vitejs.dev/guide/#scaffolding-your-first-vite-project It includes additional package.json commands to run ESLint and the TypeScript compiler independently. It uses PNPM.

The template code of the App.svelte component demonstrates the linting error.

The app renders a list of items. Each item includes a title and a link. For each item, the title is rendered along with a button to open that link in the current browser tab.

I believe this is a parsing problem because this issue occurs only on the template (which I understand the parser transforms into an AST; apologies if this is incorrect, I've never worked on anything like this); the TypeScript compiler correctly understands the code; the errors being raised are not eslint-plugin-svelte ruleset; and I've used this same configuration in React TypeScript projects with almost identical code and not experienced similar problems.

svelte parsing error in template literals

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.41.0

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

2.29.0

What did you do?

Configuration
module.exports = {
	root: true,
	extends: [
		'eslint:recommended',
		'plugin:@typescript-eslint/recommended',
		'plugin:svelte/recommended',
		'prettier'
	],
	parser: '@typescript-eslint/parser',
	plugins: ['@typescript-eslint'],
	parserOptions: {
		sourceType: 'module',
		ecmaVersion: 2020,
		extraFileExtensions: ['.svelte']
	},
	env: {
		browser: true,
		es2017: true,
		node: true
	},
	overrides: [
		{
			files: ['*.svelte'],
			parser: 'svelte-eslint-parser',
			parserOptions: {
				parser: '@typescript-eslint/parser'
			}
		}
	]
};

<script>
	let workaround = setInitialClassState.toString();

	function setInitialClassState() {
		// does something
	}
</script>

<svelte:head>
	<!-- This causes the new eslint-plugin-svelte to throw a parsing error -->
	{@html `<script nonce="%sveltekit.nonce%">(${setInitialClassState.toString()})();</script>`}

	<!-- This is works -->
	{@html `<script nonce="%sveltekit.nonce%">(` + workaround + `)();</script>`}
</svelte:head>

What did you expect to happen?

I migrated over to this plugin from the now deprecated eslint-plugin-svelte3. The previous one didn't throw this parsing error.

What actually happened?

/parsing-error-eslint-plugin-svelte/src/routes/+page.svelte
  11:45  error  Parsing error: ')' expected

✖ 1 problem (1 error, 0 warnings)

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/AdrianGonz97/parsing-error-eslint-plugin-svelte

Additional comments

No response

SvelteStyleElement.SvelteStartTag attributes array is empty for v0.20.0

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.27.0

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

What did you do?

Sample code:

<style src="old.scss" global></style>

What did you expect to happen?

Able to parse attributes: works in v0.19.3

Screen Shot 2022-11-10 at 11 36 57 am

What actually happened?

Parsed attributes are empty: fails in v0.20.0

Screen Shot 2022-11-10 at 11 36 10 am

Link to GitHub Repo with Minimal Reproducible Example

N/A

Additional comments

works in v0.19.3
fails in v0.20.0

Error parsing spread syntax with `lang="pug"`

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.25.0

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

What did you do?

Configuration

.eslintrc.yaml

env:
  browser: true
  es6: true
extends:
  - "eslint:recommended"
  - "plugin:svelte/recommended"
parserOptions:
  ecmaVersion: 2020
  sourceType: module

Test.svelte

<script>
  let objs = [{a: 1, b: 2}, {a: 2, b: 3}]
</script>

<template lang="pug">
  +each("objs as obj")
    p("{...obj}") {obj.a}
</template>

What did you expect to happen?

Successful parse.

What actually happened?

$ eslint Test.svelte

/home/projects/node-zm1om6/Test.svelte
7:8 error Parsing error: Unexpected token

✖ 1 problem (1 error, 0 warnings)

Link to Minimal Reproducible Example

https://stackblitz.com/edit/node-zm1om6?file=Test.svelte

Additional comments

With ("{...obj}") dropped linter issues no-unused-vars and no-undef. It seems eslint-plugin-svelte processes markup as plaintext.

With svelte-preprocess in place Svelte compiler won't issue a warning; however a genuine error would likely result in incorrect line number. Apparently preprocessor does not map original pug to resulting html (same issue with sass). Not good in compiler, it's probably a no-go for linter.

That sounds like a load of work and wontfix. However if you think it's feasible please outline the solution, I'd like to dig in.

Parsing error when using dot notation in `use` directive.

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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 and svelte-eslint-parser are you using?

What did you do?

Configuration
<!-- Paste your configuration here -->

Playground minimal reproduction here.

Same example in svelte REPL to show this is valid svelte syntax: link

<script>
  function myaction(n) {};

  const myobj = { myaction };
</script>

<!-- works -->
<div use:myaction />

<!-- Parsing error: Expected JS identifier.ESLint(FATAL) -->
<div use:myobj.myaction />

What did you expect to happen?

Parsed without error.

What actually happened?

Error: Parsing error: Expected JS identifier.ESLint(FATAL)

Link to GitHub Repo with Minimal Reproducible Example

https://ota-meshi.github.io/eslint-plugin-svelte/playground/#eJxVjkELgkAQhf/K5EkPm3ezwIMdwkNg0MWLraNM6KzsrlKI/721wuj2Zt7j45s8qSr0Ii/eCAFXbKXqEKwCNC2xFX07NMTCjNhaBCEOBcdGauqtSwD1wNKSYuie5Tv4HMA0F7yUUrGxrlG3O+xhWjcw7xwlXDHuqGiEwWC0TsLPf5E6l9oQN4BaKx1B+uhRWqzglANVyJZqQr1N88z5+sfkkmTBV/RHdQrbP7Y3vwCISlaj

Additional comments

Use case: HeadlessUI library

@typescript-eslint/no-unsafe-call with svelte-i18n and @typescript-eslint/recommended-requiring-type-checking

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.20.0

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

2.2.0

What did you do?

Configuration
module.exports = {
  parser: '@typescript-eslint/parser',
  extends: [
    'plugin:svelte/recommended',
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking'
  ],
  parserOptions: {
    project: ['./tsconfig.json'],
    extraFileExtensions: ['.svelte']
  },
  overrides: [
    {
      files: ['*.svelte'],
      parser: 'svelte-eslint-parser',
      parserOptions: {
        parser: "@typescript-eslint/parser",
      },
    },
  ],
  ignorePatterns: ['node_modules', 'dist']
}
<script lang="ts">
  import { _ } from 'svelte-i18n';
</script>

<main>
  <input name={$_('test')}>
</main>

What did you expect to happen?

No lint issues to occur.

What actually happened?

Unsafe call of an any typed value. @typescript-eslint/no-unsafe-call

for $_('test'). This doesn't happen with https://github.com/sveltejs/eslint-plugin-svelte3.

Link to Minimal Reproducible Example

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

Additional comments

No response

Extract slot prop types from `$$Slots`

Description

In ota-meshi/eslint-plugin-svelte#347 I proposed a rule to require slots and their props to be typed. In this package, those types should be used if they're present.

An example of what currently doesn't work:

App.svelte:

<Component let:arrayProp={arrayValue}>
  {#each arrayValue.filter( (val) => val.length > 10 ) as val} <!-- HERE -->
    {val}
  {/each}
</Component>

Component.svelte:

<script lang="ts">
  interface $$Slots {
    default: { arrayProp: Array<string> };
  }
</script>

<slot arrayProp={["Hello", "World", "Hello World"]} />

Here, on the marked line, I get the eslint error @typescript-eslint/no-unsafe-call - I presume that's because the parser does not infer that arrayValue is of type Array<string> and leaves it as any...

Conflict with `lib.dom.d.ts` when using runes

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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?

  • 9.9.0

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

What did you do?

https://sveltejs.github.io/svelte-eslint-parser/virtual-script-code/#eJyrVkrOT0lVslKyKU4uyiwoUchJzEu3jVEqKY5RsovJy0ktUahWyEvMTVWotYKyrBSKS4oy89IVahVsFVQKivILijU0Y/Ji8mz0IWYA9cH0KNUCAEUdIQ4=

<script lang="ts">
let { name }: { name: string } = $props()

</script>
{ name }

What did you expect to happen?

Name should be able to be defined and not conflict with globals

What actually happened?

It conflicts with the DOM lib globals

Link to GitHub Repo with Minimal Reproducible Example

https://sveltejs.github.io/svelte-eslint-parser/virtual-script-code/#eJyrVkrOT0lVslKyKU4uyiwoUchJzEu3jVEqKY5RsovJy0ktUahWyEvMTVWotYKyrBSKS4oy89IVahVsFVQKivILijU0Y/Ji8mz0IWYA9cH0KNUCAEUdIQ4=

Additional comments

No response

Scope Manager should return module scope for top level statements

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.34.0

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

What did you do?

Configuration
{ parserOptions: { sourceType: 'module' } }
<script>
import imported from "mod";
const local = true;
</script>

What did you expect to happen?

When writing an ESLint rule I expect to get a module scope for visitors with selectors ImportDeclaration or VariableDeclaration or any other top-level statement.

What actually happened?

context.getScope returns the global scope and not the expected module scope.

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/DMartens/svelte-eslint-parser-scope-bug
The test is in the scope.js file

Additional comments

The default scope manager and other custom parser / scope manager return a module scope.
They only return the global scope for Program (which for svelte would be the SvelteScriptElement).
I am willing to provide a PR to fix this.

JSDoc types are lost in svelte files (typescript-eslint)

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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?

9.3.0

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

What did you do?

Configuration
import tsEslint from 'typescript-eslint'
import epSvelte from 'eslint-plugin-svelte'
import svelteParser from 'svelte-eslint-parser'

export default [
  ...tsEslint.configs.strictTypeChecked,
  ...epSvelte.configs['flat/recommended'],
  {
    languageOptions: {
      parser: tsEslint.parser,
      parserOptions: {
        project: true,
        programs: false,
        extraFileExtensions: ['.svelte']
      },
    },
  },
  {
    files: ['**/*.svelte'],
    languageOptions: {
      parser: svelteParser,
      parserOptions: {
        parser: tsEslint.parser,
      }
    },
  },
]
<script>
  /** @param {number} x  */
  function test(x) {
    return x+1
  }
</script>

While both .svelte and .js files are scanned by ESLint the same function yields different results:

// test.svelte
<script>
  /** @param {number} x */
  function test(x) {
    return x+1
  }
</script>
// test.js
  /** @param {number} x */
  function test(x) {
    return x+1
  }

npx eslint src

test.js
   2:10  error  'test' is defined but never used     @typescript-eslint/no-unused-vars

test.svelte
    3:12  error  'test' is defined but never used  @typescript-eslint/no-unused-vars
    4:5   error  Unsafe return of an `any` typed value  @typescript-eslint/no-unsafe-return
    5:12  error  Invalid operand for a '+' operation. Operands must each be a number or string. Got `any`  @typescript-eslint/restrict-plus-operands

What did you expect to happen?

I expected the same code to produce the same warnings, irrespective of appearing in a .svelte or .js file.

What actually happened?

It seems like the typescript-eslint parser cannot parse type information from the code in the .svelte files. Maybe the svelte-parser strips JSDoc comments from the code before forwarding it to the typescript parser?

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/falco467/svelte-jsdoc-typescript-example

Additional comments

Migrated from eslint-plugin-svelte since it is a parser problem: sveltejs/eslint-plugin-svelte#767

Type imports cause parse errors

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.16.0

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

What did you do?

Configuration
root: true
parser: '@typescript-eslint/parser'

extends:
  - eslint:recommended
  - plugin:@typescript-eslint/recommended
  - prettier

plugins:
  - svelte3
  - '@typescript-eslint'

overrides:
  - files: ['*.svelte']
    parser: svelte-eslint-parser

settings:
  svelte3/typescript: () => require('typescript')

rules:
  no-unused-vars:
    - error
    - argsIgnorePattern: '^_'
      varsIgnorePattern: '^_'
      caughtErrorsIgnorePattern: '^_'

  '@typescript-eslint/no-unused-vars':
    - error
    - argsIgnorePattern: '^_'
      varsIgnorePattern: '^_'
      caughtErrorsIgnorePattern: '^_'

parserOptions:
  sourceType: module
  ecmaVersion: 2020

env:
  browser: true
  es2017: true
  node: true

src/routes/index.svelte

<script lang="ts">
  import type { Thing } from '$lib';
</script>

src/lib/index.ts

export type Thing = string;

What did you expect to happen?

The lint should pass.

What actually happened?

$ pnpm lint

> [email protected] lint /mcve
> prettier --check --plugin-search-dir=. . && eslint .

Checking formatting...
All matched files use Prettier code style!

src/routes/index.svelte
  2:15  error  Parsing error: Unexpected token {

✖ 1 problem (1 error, 0 warnings)

 ELIFECYCLE  Command failed with exit code 1.

Link to Minimal Reproducible Example

https://github.com/Stonks3141/mcve

Additional comments

If I replace parser: svelte-eslint-parser with processor: svelte3/svelte3 in .eslintrc.yml, ESlint outputs this:

$ pnpm lint

> [email protected] lint /mcve
> prettier --check --plugin-search-dir=. . && eslint .

Checking formatting...
All matched files use Prettier code style!

src/routes/index.svelte
  0:0  error  Cannot read properties of undefined (reading 'ESNext')  TypeError

✖ 1 problem (1 error, 0 warnings)

 ELIFECYCLE  Command failed with exit code 1.

This error appears for all .svelte files.

The MCVE was made with pnpm init svelte and selecting Typescript, ESlint, and Prettier.

Parsing error with `<script>` in a string literal

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.48.0

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

2.33.0

What did you do?

I'm using Partytown with SvelteKit based on the official guide, here's the code I have in my +layout.svelte:

<script>
  import { partytownSnippet } from '@builder.io/partytown/integration'
</script>

<svelte:head>
  {@html `<script>${partytownSnippet()}</script>`}
</svelte:head>

eslint-plugin-svelte seems to get confused at the <script> part inside the string literal; I get the following error:

Parsing error: Unexpected keyword or identifier. eslint

What did you expect to happen?

The <script> inside the string should be recognized as a string.

What actually happened?

It seems to be confused by the <script> part, it may worth noting that if you changed <script> to any other tag like <style> here the error would go away, so the issue must be specific to <script>.

Link to GitHub Repo with Minimal Reproducible Example

Repro: https://github.com/aradalvand/eslint-plugin-svelte-bug

Go to src/routes/+layout.svelte — you'll see the error:

image

Additional comments

No response

Attribute findParentComponent gets stuck in infinite loop

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

  • I'm using eslint-plugin-svelte. (*.svelte file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)
  • I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
  • 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.50.0

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

What did you do?

Configuration
module.exports = {
  root: true,
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:svelte/recommended',
    'prettier'
  ],
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  parserOptions: {
    sourceType: 'module',
    ecmaVersion: 2020,
    extraFileExtensions: ['.svelte']
  },
  env: {
    browser: true,
    es2017: true,
    node: true
  },
  overrides: [
    {
      files: ['*.svelte'],
      parser: 'svelte-eslint-parser',
      parserOptions: {
        parser: '@typescript-eslint/parser'
      }
    }
  ]
};
  1. create a new svelte-kit demo app with npm create svelte@latest, with typescript syntax, and eslint and prettier
  2. add the component below
  3. run npm install
  4. run npx eslint "src/**/*.svelte"
<script lang="ts">
  export let collapsed = false;
</script>

<div>
  {#if !collapsed}
    <svelte:self collapsed let:something>
      <slot {something} />
    </svelte:self>
  {/if}
</div>

What did you expect to happen?

I expected eslint to parse the file properly and show me any issues

What actually happened?

I left the command run for a while, but nothing happened.
When I ran it in VS Code's js debug terminal and stopped it, I saw that it was getting stuck inside the while (parent && parent.type !== "SvelteElement") loop in attr.ts @ function findParentComponent.

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/SeppahBaws/svelte-eslint-parser-infinite-loop

the component causing the infinite loop is in src/lib/Recursive.svelte

Additional comments

Looking a bit closer at the code, it seems like it's trying to walk the node tree upwards, but accidentally reassigns parent with the exact same value it already has (node.parent), thus ending up in an infinite loop.

I fixed it locally by replacing the line in the while loop with parent = parent.parent in the attr.js file inside node_modules. However I'm not familiar with this codebase, so when I tried to apply the same fix inside the attr.ts file in this repo, TypeScript was complaining about mismatching types.

Getting an error "cannot read properties of undefined reading range"

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.41.0

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

2.30.0

What did you do?

``` module.exports = { root: true, extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:svelte/recommended', 'prettier' ], parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint'], parserOptions: { sourceType: 'module', ecmaVersion: 2020, extraFileExtensions: ['.svelte'] }, env: { browser: true, es2017: true, node: true }, overrides: [ { files: ['*.svelte'], parser: 'svelte-eslint-parser', parserOptions: { parser: '@typescript-eslint/parser' } } ] }; ```
Wrapper.svelte

<slot />

Item.svelte

<script lang="ts">
  import Wrapper from './Wrapper.svelte';
</script>

<Wrapper>
  {@const text = 'text'}
  <button>
    {text}
  </button>
</Wrapper>

What did you expect to happen?

It shouldn't return an error

What actually happened?

eslint .

src/routes/+page.svelte
  0:0  error  Parsing error: Cannot read properties of undefined (reading 'range')

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/Iuriy-Budnikov/eslint-plugin-svelte-bug

Additional comments

It looks like it doesn't support {@const text = 'text'} inside the wrapper component with slot

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.