Open MathiasWP opened 7 months ago
Hey, I had it working with the following config:
import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import eslintPluginSvelte from "eslint-plugin-svelte";
import globals from "globals";
import svelteParser from "svelte-eslint-parser";
import tsEslint from "typescript-eslint";
export default tsEslint.config(
js.configs.recommended,
...tsEslint.configs.recommended,
...eslintPluginSvelte.configs["flat/recommended"],
eslintConfigPrettier,
...eslintPluginSvelte.configs["flat/prettier"],
{
languageOptions: {
ecmaVersion: 2022,
sourceType: "module",
globals: { ...globals.node, ...globals.browser },
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser,
extraFileExtensions: [".svelte"],
},
},
},
{
ignores: [
"**/.svelte-kit",
"**/.vercel",
"**/.yarn",
"**/build",
"**/node_modules",
"**/package",
],
},
);
Hope it helps
Edit: updated with better imports and ignores
Also working for me. According to the rollout tracker there is support.
import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import eslintPluginSvelte from "eslint-plugin-svelte";
import globals from "globals";
import tsEslint from "typescript-eslint";
import vitest from "eslint-plugin-vitest";
import playwright from "eslint-plugin-playwright";
export default [
js.configs.recommended,
...tsEslint.configs.recommended,
...eslintPluginSvelte.configs["flat/recommended"],
eslintConfigPrettier,
{
...playwright.configs["flat/playwright"],
files: ["tests/**"]
},
vitest.configs.recommended,
...eslintPluginSvelte.configs["flat/prettier"],
{
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
globals: { ...globals.node, ...globals.browser },
parserOptions: {
extraFileExtensions: [".svelte"]
}
}
},
{
ignores: [
".svelte-kit",
"build",
"package",
"coverage",
"node_modules",
"playwright.config.js"
]
}
];
Hey, I had it working with the following config:
import js from "@eslint/js"; import tsParser from "@typescript-eslint/parser"; import eslintConfigPrettier from "eslint-config-prettier"; import eslintPluginSvelte from "eslint-plugin-svelte"; import globals from "globals"; import svelteParser from "svelte-eslint-parser"; import tsEslint from "typescript-eslint"; export default tsEslint.config( js.configs.recommended, ...tsEslint.configs.recommended, ...eslintPluginSvelte.configs["flat/recommended"], eslintConfigPrettier, ...eslintPluginSvelte.configs["flat/prettier"], { languageOptions: { ecmaVersion: 2022, sourceType: "module", globals: { ...globals.node, ...globals.browser }, parser: svelteParser, parserOptions: { parser: tsParser, extraFileExtensions: [".svelte"], }, }, }, { ignores: [".svelte-kit", "build", "package"] }, );
Hope it helps
Thank you for helping out, i really appreciate it! This config works for my Svelte files it seems like, but in almost all my TypeScript files i get a 5:14 error Parsing error: Unexpected token {
error (is usually crashes at imports like import { type Foo } from 'bar'
.
Also working for me. According to the rollout tracker there is support.
import js from "@eslint/js"; import eslintConfigPrettier from "eslint-config-prettier"; import eslintPluginSvelte from "eslint-plugin-svelte"; import globals from "globals"; import tsEslint from "typescript-eslint"; import vitest from "eslint-plugin-vitest"; import playwright from "eslint-plugin-playwright"; export default [ js.configs.recommended, ...tsEslint.configs.recommended, ...eslintPluginSvelte.configs["flat/recommended"], eslintConfigPrettier, { ...playwright.configs["flat/playwright"], files: ["tests/**"] }, vitest.configs.recommended, ...eslintPluginSvelte.configs["flat/prettier"], { languageOptions: { ecmaVersion: "latest", sourceType: "module", globals: { ...globals.node, ...globals.browser }, parserOptions: { extraFileExtensions: [".svelte"] } } }, { ignores: [ ".svelte-kit", "build", "package", "coverage", "node_modules", "playwright.config.js" ] } ];
Thank you for helping out, i appreciate it! This config works fine for me on TypeScript files, but it does not work on Svelte files. The funny thing is that i tried to merge your and @GauBen's configs (because the one works with TS and the other with Svelte), but with no luck. :/
@MathiasWP : I had the same problem as you, but I got it working by adding files: ["**/*.svelte"],
to the configuration object block that contains languageOptions
.
My understanding, is that by adding files: ["**/*.svelte"],
into this object, you tell it that this override will only apply to .svelte
files.
{
files: ["**/*.svelte"],
languageOptions: {
ecmaVersion: 2022,
sourceType: "module",
parser: svelteParser,
parserOptions: {
parser: tsParser,
extraFileExtensions: [".svelte"],
},
},
},
I am not sure what the extraFileExtensions: [".svelte"],
is supposed to do? It seem that I can remove it without any ill effect.
Hope this helps.
@MathiasWP : I had the same problem as you, but I got it working by adding
files: ["**/*.svelte"],
to the configuration object block that containslanguageOptions
.My understanding, is that by adding
files: ["**/*.svelte"],
into this object, you tell it that this override will only apply to.svelte
files.{ files: ["**/*.svelte"], languageOptions: { ecmaVersion: 2022, sourceType: "module", parser: svelteParser, parserOptions: { parser: tsParser, extraFileExtensions: [".svelte"], }, }, },
I am not sure what the
extraFileExtensions: [".svelte"],
is supposed to do? It seem that I can remove it without any ill effect. Hope this helps.
Thank you so much! This solved the issue for me! 🎉
For completeness, here is a full eslint
"flat file" configuration that works for Svelte projects that use TypeScript.
It also includes Prettier linting.
Maybe an example of such a "flat file" config could be added to the doc of eslint-plugin-svelte
, because so far there are only examples of the "old" type of config file (if I'm not mistaken).
// eslint.config.cjs
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import eslintPluginSvelte from 'eslint-plugin-svelte';
import js from '@eslint/js';
import svelteParser from 'svelte-eslint-parser';
import tsEslint from 'typescript-eslint';
import tsParser from '@typescript-eslint/parser';
export default [
js.configs.recommended,
...tsEslint.configs.strict,
...eslintPluginSvelte.configs['flat/recommended'],
eslintPluginPrettierRecommended, // must be last to override conflicting rules.
{
rules: {
semi: ['warn', 'always'],
quotes: [
'warn',
'single',
{ avoidEscape: true, allowTemplateLiterals: true },
],
'no-nested-ternary': 'error',
'linebreak-style': ['error', 'unix'],
'no-cond-assign': ['error', 'always'],
'no-console': 'error',
'@typescript-eslint/sort-type-constituents': 'error',
'sort-imports': [
'error',
{
ignoreCase: true,
ignoreDeclarationSort: false,
ignoreMemberSort: false,
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
allowSeparatedGroups: true,
},
],
},
},
{
files: ['**/*.svelte'],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsParser,
},
},
rules: {
'svelte/no-target-blank': 'error',
'svelte/no-at-debug-tags': 'error',
'svelte/no-reactive-functions': 'error',
'svelte/no-reactive-literals': 'error',
},
},
];
I found why my config file was not working with ts files in vscode, yet the command line interface worked as expected!
I needed this config line in vscode: "eslint.experimental.useFlatConfig": true
For completeness, here is a full
eslint
"flat file" configuration that works for Svelte projects that use TypeScript. It also includes Prettier linting.Maybe an example of such a "flat file" config could be added to the doc of
eslint-plugin-svelte
, because so far there are only examples of the "old" type of config file (if I'm not mistaken).// eslint.config.cjs import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; import eslintPluginSvelte from 'eslint-plugin-svelte'; import js from '@eslint/js'; import svelteParser from 'svelte-eslint-parser'; import tsEslint from 'typescript-eslint'; import tsParser from '@typescript-eslint/parser'; export default [ js.configs.recommended, ...tsEslint.configs.strict, ...eslintPluginSvelte.configs['flat/recommended'], eslintPluginPrettierRecommended, // must be last to override conflicting rules. { rules: { semi: ['warn', 'always'], quotes: [ 'warn', 'single', { avoidEscape: true, allowTemplateLiterals: true }, ], 'no-nested-ternary': 'error', 'linebreak-style': ['error', 'unix'], 'no-cond-assign': ['error', 'always'], 'no-console': 'error', '@typescript-eslint/sort-type-constituents': 'error', 'sort-imports': [ 'error', { ignoreCase: true, ignoreDeclarationSort: false, ignoreMemberSort: false, memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], allowSeparatedGroups: true, }, ], }, }, { files: ['**/*.svelte'], languageOptions: { parser: svelteParser, parserOptions: { parser: tsParser, }, }, rules: { 'svelte/no-target-blank': 'error', 'svelte/no-at-debug-tags': 'error', 'svelte/no-reactive-functions': 'error', 'svelte/no-reactive-literals': 'error', }, }, ];
I agree, having an example would help a lot
This should be added to the readme in the parser configuration section. We also don't have to import the ts parser see here https://typescript-eslint.io/packages/typescript-eslint/#manually-configuring-our-plugin-and-parser.
This should be added to the readme in the parser configuration section. We also don't have to import the ts parser see here typescript-eslint.io/packages/typescript-eslint/#manually-configuring-our-plugin-and-parser.
Thanks, feels nice to remove @typescript-eslint/parser
I managed to lint both TypeScript *.svelte
and *.ts
:
import eslint from "@eslint/js";
import pluginImport from "eslint-plugin-import";
import svelteEslint from "eslint-plugin-svelte";
import globals from "globals";
import svelteParser from "svelte-eslint-parser";
import tsEslint from "typescript-eslint";
export default [
eslint.configs.recommended,
...tsEslint.configs.recommended,
...svelteEslint.configs["flat/recommended"],
{
files: ["**/*.svelte"],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser
},
globals: {
...globals.browser
}
}
},
{
files: ["**/*.ts"],
languageOptions: {
parser: tsEslint.parser
}
},
{
plugins: {
"@typescript-eslint": tsEslint.plugin,
import: pluginImport
},
rules: {
semi: "warn",
"svelte/sort-attributes": "warn"
}
}
];
Thanks for all the config hints - I'm new to svelte and eslint 9 is complaining with this config about eslint.config.cjs
> eslint .
(node:19898) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
Oops! Something went wrong! :(
ESLint: 9.0.0
/Users/scotte/Development/Projects/wordacle/eslint.config.cjs:1
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
^^^^^^
SyntaxError: Cannot use import statement outside a module
Running it with npx eslint .
@szinn Change the filename to eslint.config.js
Ah, I also reinstalled modules - prettier config caused grief as well
This is wonderful! I was able to use and extend the above into a config that supports custom configs for my test files, with the addition of the markdown linter, and the jsdoc linter. Hopefully this helps others build even better ones!
eslint.config.js
I am not sure what the
extraFileExtensions: [".svelte"],
is supposed to do? It seem that I can remove it without any ill effect. Hope this helps.
@robinengler I wanted to answer this Q because it's important to understand why thigns are done!
The ts parser will ignore files with file extensions it doesn't expect (such as .svelte
). The svelte parser is passed a ts parser instance to handle parsing typescript inside svelte files (sorry if that's a confusing explanation). To make sure the ts parser will run on this code, we pass the extraFileExtensions
parameter to the svelte parser, which in turn passes it to the ts parser to ensure it parses the typescript in svelte files for us. If you don't, the ts parser will report the following error for every svelte file:
The extension for the file (`.svelte`) is non-standard. You should add `parserOptions.extraFileExtensions` to your config
If you weren't getting any errors from removing this line, it could be that your config was not actually linting the .svelte
files in your project. Hope this helps!
I think that it helps you to specify files
for each config object like below:
import globals from 'globals';
import js from '@eslint/js';
import tseslint from 'typescript-eslint' // v7
import prettierConfig from 'eslint-config-prettier';
import svelte from 'eslint-plugin-svelte';
import svelteParser from 'svelte-eslint-parser';
/** @type {import('typescript-eslint').Config} */
export default = [
...[
js.configs.recommended,
...tseslint.configs.strictTypeChecked, // typescript-eslint set `['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts']` to `files`
prettierConfig, // eslint-config-prettier does not turn 'svelte/*' rules off
{ // overrides options should be after other config
languageOptions: {
parser: tseslint.parser,
parserOptions: {
sourceType: 'module',
extraFileExtensions: ['.svelte']
},
globals: { ...globals.browser, ...globals.node },
},
rules: { /* rules for js/ts/svelte */ } // don't set 'svelte/*' rules here
}
].map(conf => ({ ...conf, files: ['**/*.js', '**/*.ts', '**/*.svelte'] })), // To override `files` is so important!!
...svelte.configs['flat/recommended'], // eslint-plugin-svelte set `['*.svelte', '**/*.svelte']` to `files`
...svelte.configs['flat/prettier'], // if non svelte files occur 'svelte/*' error, these element should be set `files`
{ // your config should be after
files: ['*.svelte', '**/*.svelte'], // the same value as eslint-plugin-svelte `files` option
languageOptions: {
parser: svelteParser,
parserOptions: { parser: tseslint.parser }
},
// ↓ rule types; sveltejs/eslint-plugin-svelte #735
/** @type {import('eslint').Linter.RulesRecord} */
rules: { /* rules for svelte */ }
},
{
// other override settings. e.g. for `files: ['**/*.test.*']`
},
{ ignores: ['node_modules/', /* other ignores */] } // overrides global ignores
];
It because that typescript-eslint
set ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts']
to files
.
[!NOTE]
'**/*.js'
pattern may be not overridden with'*.js'
pattern.
Using typescript-eslint helper function config(...)
as below provides the almost same flat-config array as above.
I haven't been able to get any of the above configs working with eslint 9.3.0 and typescript-eslint 8.0.0-alpha.20 for .svelte files but it does work for all .js and .ts files.
From https://github.com/typescript-eslint/typescript-eslint/issues/8211:
Note that we do not plan on backporting ESLint v9 support to v7 versions of typescript-eslint. There are a lot of breaking changes inherent to our ESLint v9 support.
The error I'm seeing on .svelte files is:
0:0 error Parsing error: "parserOptions.programs" has been provided for @typescript-eslint/parser. The file was not found in any of the provided program instance(s): src\routes\+page.svelte
Here is an example config that is getting this error.
import js from '@eslint/js';
import ts from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
const tsConfig = ts.config({
files: ['**/*.js', '**/*.ts', '**/*.svelte'],
extends: [
js.configs.recommended,
...ts.configs.strictTypeChecked,
...ts.configs.stylisticTypeChecked,
prettier
],
languageOptions: {
globals: {
...globals.browser,
...globals.nodeBuiltin
},
parserOptions: {
project: './tsconfig.eslint.json',
tsconfigRootDir: import.meta.dirname,
extraFileExtensions: ['.svelte']
}
}
});
const svelteConfig = ts.config({
files: ['**/*.svelte'],
extends: [...svelte.configs['flat/recommended'], ...svelte.configs['flat/prettier']],
languageOptions: {
parserOptions: {
parser: ts.parser
}
}
});
export default ts.config(...tsConfig, ...svelteConfig, {
ignores: ['.svelte-kit/']
});
{
"extends": "./tsconfig.json",
"files": ["eslint.config.js", "svelte.config.js", "vite.config.ts"]
}
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
}
For completeness, here is a full
eslint
"flat file" configuration that works for Svelte projects that use TypeScript. It also includes Prettier linting.Maybe an example of such a "flat file" config could be added to the doc of
eslint-plugin-svelte
, because so far there are only examples of the "old" type of config file (if I'm not mistaken).// eslint.config.cjs import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; import eslintPluginSvelte from 'eslint-plugin-svelte'; import js from '@eslint/js'; import svelteParser from 'svelte-eslint-parser'; import tsEslint from 'typescript-eslint'; import tsParser from '@typescript-eslint/parser'; export default [ js.configs.recommended, ...tsEslint.configs.strict, ...eslintPluginSvelte.configs['flat/recommended'], eslintPluginPrettierRecommended, // must be last to override conflicting rules. { rules: { semi: ['warn', 'always'], quotes: [ 'warn', 'single', { avoidEscape: true, allowTemplateLiterals: true }, ], 'no-nested-ternary': 'error', 'linebreak-style': ['error', 'unix'], 'no-cond-assign': ['error', 'always'], 'no-console': 'error', '@typescript-eslint/sort-type-constituents': 'error', 'sort-imports': [ 'error', { ignoreCase: true, ignoreDeclarationSort: false, ignoreMemberSort: false, memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], allowSeparatedGroups: true, }, ], }, }, { files: ['**/*.svelte'], languageOptions: { parser: svelteParser, parserOptions: { parser: tsParser, }, }, rules: { 'svelte/no-target-blank': 'error', 'svelte/no-at-debug-tags': 'error', 'svelte/no-reactive-functions': 'error', 'svelte/no-reactive-literals': 'error', }, }, ];
Thanks for this! I was wondering if we could see the package.json
for this to look at the package versions. I'm running into the same issue as @kkirkfield and I think seeing the versions of the package used would help me debug the issue.
Did you look at the one I posted above (hidden in a details
tag)? It continues to work, and I've upgraded since I posted to every single more recent release.
The primary difference I see is I am not using the pre-release alpha, but the stable release:
"@typescript-eslint/eslint-plugin": "^7.11.0",
Here is the relevant section of my package.json
:
"devDependencies": {
"@eslint/js": "^9.3.0",
"@floating-ui/dom": "^1.6.5",
"@flydotio/dockerfile": "^0.5.7",
"@fontsource/fira-mono": "^5.0.13",
"@inlang/cli": "^2.18.0",
"@inlang/paraglide-js": "^1.9.1",
"@inlang/paraglide-sveltekit": "^0.8.6",
"@internationalized/date": "^3.5.4",
"@mockoon/cli": "^8.1.1",
"@playwright/test": "^1.44.1",
"@skeletonlabs/skeleton": "^2.10.0",
"@skeletonlabs/tw-plugin": "^0.4.0",
"@sveltejs/adapter-node": "^5.0.1",
"@sveltejs/kit": "^2.5.10",
"@sveltejs/vite-plugin-svelte": "^3.1.0",
"@tailwindcss/forms": "^0.5.7",
"@testing-library/jest-dom": "^6.4.5",
"@testing-library/svelte": "^5.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/d3": "^7.4.3",
"@types/eslint": "^8.56.10",
"@types/node": "^20.12.12",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@vitest/ui": "^1.6.0",
"autoprefixer": "^10.4.19",
"bits-ui": "^0.21.10",
"browser-tab-id": "^0.0.8",
"browserslist": "^4.23.0",
"cssnano": "^7.0.1",
"dotenv": "^16.4.5",
"drizzle-kit": "^0.21.4",
"eslint": "^9.3.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsdoc": "^48.2.6",
"eslint-plugin-markdown": "^5.0.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-svelte": "^2.39.0",
"formsnap": "^1.0.0",
"globals": "^15.3.0",
"jsdom": "^24.1.0",
"pgtools": "^1.0.1",
"postcss": "^8.4.38",
"postcss-cli": "^11.0.0",
"postcss-import": "^16.1.0",
"postcss-nesting": "^12.1.5",
"postcss-preset-env": "^9.5.14",
"postcss-simple-vars": "^7.0.1",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.3",
"prettier-plugin-tailwindcss": "^0.5.14",
"stylelint": "^16.6.1",
"stylelint-config-standard": "^36.0.0",
"stylelint-order": "^6.0.4",
"svelte": "5.0.0-next.143",
"svelte-check": "^3.7.1",
"svelte-eslint-parser": "^0.36.0",
"svelte2tsx": "^0.7.8",
"sveltekit-rate-limiter": "^0.5.1",
"sveltekit-superforms": "^2.14.0",
"tailwindcss": "^3.4.3",
"tslib": "^2.6.2",
"tsx": "^4.11.0",
"typescript": "^5.4.5",
"typescript-eslint": "^7.11.0",
"vite": "^5.2.12",
"vitest": "^1.6.0"
},
"type": "module",
"dependencies": {
"@honeycombio/opentelemetry-node": "^0.7.2",
"@inlang/language-tag": "^1.5.1",
"@kripod/uuidv7": "^0.3.4",
"@lucia-auth/adapter-drizzle": "^1.0.7",
"@opentelemetry/api": "^1.8.0",
"@opentelemetry/auto-instrumentations-node": "^0.46.1",
"@opentelemetry/context-zone": "^1.24.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.51.1",
"@opentelemetry/instrumentation": "^0.51.1",
"@opentelemetry/instrumentation-document-load": "^0.38.0",
"@opentelemetry/instrumentation-fetch": "^0.51.1",
"@opentelemetry/instrumentation-long-task": "^0.38.0",
"@opentelemetry/instrumentation-user-interaction": "^0.38.0",
"@opentelemetry/instrumentation-xml-http-request": "^0.51.1",
"@opentelemetry/resources": "^1.24.1",
"@opentelemetry/sdk-node": "^0.51.1",
"@opentelemetry/sdk-trace-web": "^1.24.1",
"@opentelemetry/semantic-conventions": "^1.24.1",
"@sendgrid/mail": "^8.1.3",
"@sentry/sveltekit": "^8.5.0",
"arctic": "^1.9.0",
"connect-web-sdk": "^1.1.0",
"d3": "^7.9.0",
"drizzle-orm": "^0.30.10",
"drizzle-zod": "^0.5.1",
"lucia": "^3.2.0",
"lucide-svelte": "^0.379.0",
"oslo": "^1.2.0",
"postgres": "^3.4.4",
"redis": "^4.6.14",
"svelte-idb-store": "^0.2.0",
"svelte-persisted-store": "^0.9.4",
"svelte-ux": "^0.64.1",
"zod": "^3.23.8"
},
"engines": {
"node": "^20.13.1",
"npm": "^10.5.0",
"pnpm": "^9.1.3"
}
Did you look at the one I posted above (hidden in a
details
tag)? It continues to work, and I've upgraded since I posted to every single more recent release.The primary difference I see is I am not using the pre-release alpha, but the stable release:
"@typescript-eslint/eslint-plugin": "^7.11.0",
When I try to install this package via npm install -D @typescript-eslint/eslint-plugin
, I get the following error:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: palette-town@0.0.0
npm ERR! Found: eslint@9.4.0
npm ERR! node_modules/eslint
npm ERR! dev eslint@"^9.4.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer eslint@"^8.56.0" from @typescript-eslint/parser@7.11.0
npm ERR! node_modules/@typescript-eslint/parser
npm ERR! peer @typescript-eslint/parser@"^7.0.0" from @typescript-eslint/eslint-plugin@7.11.0
npm ERR! node_modules/@typescript-eslint/eslint-plugin
npm ERR! dev @typescript-eslint/eslint-plugin@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
I run into a similar error when trying to install typescript-eslint via npm i -D typescript-eslint
:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: palette-town@0.0.0
npm ERR! Found: eslint@9.4.0
npm ERR! node_modules/eslint
npm ERR! dev eslint@"^9.4.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer eslint@"^8.56.0" from typescript-eslint@7.11.0
npm ERR! node_modules/typescript-eslint
npm ERR! dev typescript-eslint@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
My understanding is both these packages (typescript-eslint
and @typescript-eslint/eslint-plugin
require version 8 of eslint, but I'm using version 9. The part where I get confused is how to get around this since, in your package.json
, it seems that you were able to get these packages installed while using eslint version 9. Attached below is my package.json
devDependencies for extra context.
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"@tsconfig/svelte": "^5.0.2",
"autoprefixer": "^10.4.19",
"eslint": "^9.4.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-svelte": "^2.39.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.5",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.3",
"prettier-plugin-tailwindcss": "^0.6.0",
"svelte": "^4.2.17",
"svelte-check": "^3.6.7",
"tailwindcss": "^3.4.3",
"tslib": "^2.6.2",
"typescript": "^5.2.2",
"vite": "^5.2.0"
},
Thanks for all your comments! I still don't know the best practices for integrating with typescript-eslint, but using typescript-eslint@v8-beta might work. https://x.com/tseslint/status/1795205941647884611
While the provided configs work for the simple recommended ruleset I cannot get it to work with the actual type-checking configs of typescript-eslint. To enable actual type-parsing, we need to enable the project: true
parser option. And as soon as that is enabled, the error reads:
Parsing error: "parserOptions.programs" has been provided for @typescript-eslint/parser. The file was not found in any of the provided program instance(s): src\drehscheibe.svelte
import epSvelte from 'eslint-plugin-svelte'
import svelteParser from 'svelte-eslint-parser'
import tsEslint from 'typescript-eslint'
export default [
...tsEslint.configs.strictTypeChecked,
...epSvelte.configs['flat/recommended'],
{
languageOptions: {
parser: tsEslint.parser,
parserOptions: {
project: true, // This line breaks the config (even with the other configs) - but it is needed for type-checking.
},
},
},
{
files: ['**/*.svelte'],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser,
}
},
},
]
And the inclusion of extra-file extensions doesn't make a difference. Also including the project: true in both parserOptions doesn't change anything. JS/TS Files get handled correctly, but svelte files are not recognized as soon as "project" is set to anything.
@kkirkfield It seems to work when I add programs: false
to the parserOptions of the typescript-eslint block.
@falco467
@kkirkfield It seems to work when I add
programs: false
to the parserOptions of the typescript-eslint block.
programs
is set to undefined by default, and gets computed from parserOptions.project
. When you are setting programs
to another value it is probably not running any programs for the typescript-eslint parser and is not doing what you expect. I'll try and give it a shot today and let you know what actually happens for me.
https://typescript-eslint.io/packages/parser#programs
To clarify some of the other confusion above...
If you want to use the strict type checked rules from typescript-eslint then you need to set project
and tsconfigRootDir
. If you just want to run the rules on src files then you can use project: true
and tsconfigRootDir: import.meta.dirname
. If you want to also parse your config files, then you can use project: './tsconfig.eslint.json'
and set additional files in the files
array in tsconfig.eslint.json
. See my example code above if you need.
For this setting you need to include the .svelte
file extension or the typescript-eslint parser will not run for code blocks in svelte files. There is a gotcha with this setting. It needs to be in a parser options group that applies to all files you would run the typescript-eslint parser for. The reason for this is because the computed parser options and the parser itself is a singleton. The parser options are only computed for the first file that eslint happens to run on. Setting extraFileExtensions or any other parser options in a separate group that only applies to a subset of files will be ignored (or only the first group to run will be used, and others will be ignored). typescript-eslint parser is implemented this way for performance reasons because it would be much slower to have to recreate the parser for every program. See my example code above that shows setting this config in a group that applies to all js, ts, and svelte files.
Here is a link to an issue showing how this is working as intended. https://github.com/typescript-eslint/typescript-eslint/issues/6778
There is no plan to officially backport support for eslint v9 to typescript-eslint v7. Support for eslint v9 is only officially supported in typescript-eslint v8 beta. I linked to this above in an early comment but I'm including it here as well.
From https://github.com/typescript-eslint/typescript-eslint/issues/8211:
Note that we do not plan on backporting ESLint v9 support to v7 versions of typescript-eslint. There are a lot of breaking changes inherent to our ESLint v9 support.
@kkirkfield
I could get it working initially and I didn't even know it was an issue for someone. Below is my config (yeah I know it's messy, lmk if I can make it better)
I guess the main reason I could get something working with strict type checking rules (@falco467 case) because I was using @ota-meshi typescript-eslint-parser-for-extra-files
But today I stumbled upon strange case which I've never seen before:
<script lang="ts">
export let authorization: string | undefined = undefined;
$: headers: {
Authorization: authorization ? `test ${authorization}` : undefined,
// Invalid type "never" of template literal expression. eslint (@typescript-eslint/restrict-template-expressions)
},
</script>
I am using all latest packages (literally, upgraded all just right before posting). typescript-eslint@8.0.0-alpha.29
@ota-meshi you got any ideas? could this be an issue for extra files parser?
upd: for a workaround i am currently using empty string instead of undefined:
export let authorization: string | undefined = '';
@falco467 Thanks for the suggestion! Setting programs to false seems to fix the issue I was running into. I tested various rules in .js, .ts, and .svelte files and all rules are working, including the type checked rules.
This seems to be working nicely for me along with type safety inside eslint.config.js I wanted to use the latest 'projectService' option which lint all files including the ones not included in tsconfig (thanks to @ryanatkn's find), but some ts-eslint rules error out saying "You must therefore provide a value for the "parserOptions.project" property for xyz rule" so not using it for now. Included rulesets
// @ts-check
import js from '@eslint/js';
import playwright from 'eslint-plugin-playwright';
import prettier from 'eslint-plugin-prettier/recommended';
import svelte from 'eslint-plugin-svelte';
import vitest from 'eslint-plugin-vitest';
import globals from 'globals';
import svelteParser from 'svelte-eslint-parser';
import ts from 'typescript-eslint';
/** @type {import('typescript-eslint').Config} */
export default ts.config(
js.configs.recommended,
...ts.configs.recommendedTypeChecked,
...svelte.configs['flat/recommended'],
prettier,
...svelte.configs['flat/prettier'],
{
...playwright.configs['flat/recommended'],
files: ['tests/**'], // or any other pattern
plugins: {
vitest
},
rules: {
...vitest.configs.recommended.rules
},
settings: {
vitest: {
typecheck: true
}
},
languageOptions: {
globals: {
...vitest.environments.env.globals
}
}
},
{
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: { ...globals.node, ...globals.browser },
parserOptions: {
project: true,
parser: ts.parser,
extraFileExtensions: ['.svelte'],
tsconfigRootDir: import.meta.dirname
}
}
},
{
files: ['**/*.svelte', '*.svelte'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: { ...globals.browser },
parser: svelteParser,
parserOptions: {
parser: ts.parser,
extraFileExtensions: ['.svelte']
}
},
rules: {
'import/no-named-as-default': 'off',
'import/no-named-as-default-member': 'off',
'svelte/no-target-blank': 'error',
'svelte/no-at-debug-tags': 'error',
'svelte/no-reactive-functions': 'error',
'svelte/no-reactive-literals': 'error'
}
},
{
rules: {
semi: ['warn', 'always'],
quotes: ['warn', 'single', { avoidEscape: true, allowTemplateLiterals: true }],
'no-nested-ternary': 'error',
'linebreak-style': ['error', 'unix'],
'no-cond-assign': ['error', 'always'],
'@typescript-eslint/sort-type-constituents': 'error',
'no-console': ['error', { allow: ['warn', 'error'] }]
}
},
{
files: ['**/*.config.*'],
extends: [ts.configs.disableTypeChecked]
},
{
ignores: [
'coverage',
'**/dist',
'**/build',
'**/.husky',
'**/package',
'**/.svelte-kit',
'**/docker-data',
'**/node_modules',
'src/lib/i18n/*.ts',
'.env',
'.env.*',
'!*.cjs',
'yarn.lock',
'.DS_Store',
'!.env.example',
'pnpm-lock.yaml',
'package-lock.json'
]
}
);
I am waiting for drizzle to publish eslint v9 supported plugin to use that also as that is one of the tools i use most. And it's always helpful to have a red squiggles preventing you from writing bad queries.
Something to note that I haven't see mentioned yet, typescript-eslint
version 8 added stable support for projectService
that replaces project
:
parserOptions: {
- project: true,
+ projectService: true,
The biggest new feature added in this version is the stability of our new "project service". In short, the project service is a new way to enable typed linting that is generally easier to configure and faster at runtime than our previous offerings.
The project service will automatically find the closest tsconfig.json for each file (like
project: true
). It also allows enabling typed linting for files not explicitly included in a tsconfig.json. This should remove the need for custom tsconfig.eslint.json files to lint files like eslint.config.js!Internally, the project service uses the same TypeScript APIs that editors such as VS Code use. Doing so should make it harder to accidentally configure different type information for ESLint than what you see in day-to-day editing.
That's what works for me:
"@eslint/js": "^9.8.0",
"typescript-eslint": "^8.0.0",
"eslint-plugin-svelte": "^2.43.0",
import js from "@eslint/js";
import ts from "typescript-eslint";
import svelte from "eslint-plugin-svelte";
import svelte_config from "./svelte.config.js";
/** @type {import("eslint").Linter.Config[]} */
export default [
// js
js.configs.recommended,
// ts
...ts.configs.recommendedTypeChecked,
...ts.configs.strictTypeChecked,
...ts.configs.stylisticTypeChecked,
// ts config
{
rules: {
// ...
},
},
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
// other plugins
// ...
// svelte
...svelte.configs["flat/recommended"],
// svelte config
{
rules: {
// ...
},
},
{
files: ["**/*.svelte"],
languageOptions: {
parserOptions: {
extraFileExtensions: [".svelte"],
parser: ts.parser,
svelteConfig: svelte_config,
},
},
},
// prettier
prettier
...svelte.configs["flat/prettier"],
// other
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
},
ignores: ["build/", ".svelte-kit/"],
},
];
This worked for me. I have a monorepo using @stylistic/eslint-plugin
to format code, no prettier.
import stylisticEslint from '@stylistic/eslint-plugin';
import sveltePlugin from 'eslint-plugin-svelte';
import globals from "globals";
import svelteParser from "svelte-eslint-parser";
import tsEslint, { config, configs as tsConfigs } from 'typescript-eslint';
import svelteConfig from "./frontend/svelte.config.js";
export default config(
...tsConfigs.strictTypeChecked,
...tsConfigs.stylisticTypeChecked,
stylisticEslint.configs['recommended-flat'],
{
name: "stylistic",
plugins: {
'@stylistic': stylisticEslint,
},
languageOptions: {
parser: tsEslint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'@typescript-eslint/no-require-imports': ['off'],
"@typescript-eslint/restrict-template-expressions": ['off'],
},
},
...sveltePlugin.configs["flat/recommended"],
{
name: "svelte",
files: ["**/*.svelte"],
plugins: {
'svelte': sveltePlugin,
},
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser,
extraFileExtensions: [".svelte"],
svelteConfig: svelteConfig,
},
}
},
{
name: 'globals',
languageOptions: {
globals: {
...globals.browser,
...globals.node,
}
}
},
{
name: 'ignores',
ignores: ["**/build", "**/.svelte-kit", "**/dist", "**/*.config.js", "**/*.config.ts", "**/wallaby.js"]
}
)
and my .vscode/settings.json
:
{
"eslint.format.enable": true,
"editor.formatOnSave": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"svelte"
],
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[svelte]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
}
}
Before You File a Bug Report Please Confirm You Have Done The Following...
What version of ESLint are you using?
9.0.0
What version of
eslint-plugin-svelte
are you using?2.36.0
What did you do?
Configuration
``` import globals from "globals"; import pluginJs from "@eslint/js"; import tseslint from "typescript-eslint"; import eslintPluginSvelte from 'eslint-plugin-svelte'; export default [ { ignores: ['.svelte-kit'] }, { languageOptions: { globals: globals.browser } }, pluginJs.configs.recommended, ...tseslint.configs.recommended, ...eslintPluginSvelte.configs['flat/recommended'], ]; ```What did you expect to happen?
The linter to be happy
What actually happened?
Link to GitHub Repo with Minimal Reproducible Example
https://github.com/MathiasWP/eslint-9-svelte-typescript-error
Additional comments
No response