I'm new to Svelte, but I'm liking it so far. I've written a simple tic-tac-toe app using Svelte & TypeScript to practice with it, and now I'm adding the tooling that I prefer. I normally use a combined eslint/prettier setup, relying on the eslint-plugin-prettier to marry the two together. However, for Svelte, this is not working.
To clarify, ESLint works fine on its own. Prettier works fine on its own. However, when I combine them is when the problem arrises.
TypeScript
All of these scenarios use this TypeScript config:
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"strict": true
},
"include": ["src/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "public/*"]
}
Standalone ESLint
Here is my .eslintrc.js for running eslint standalone:
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking'
],
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
extraFileExtensions: ['.svelte']
},
env: {
es6: true,
browser: true
},
overrides: [
{
files: ['*.svelte'],
processor: 'svelte3/svelte3'
}
],
settings: {
'svelte3/typescript': require('typescript'),
// ignore style tags in Svelte because of Tailwind CSS
// See https://github.com/sveltejs/eslint-plugin-svelte3/issues/70
'svelte3/ignore-styles': () => true
},
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['node_modules']
};
I run it with eslint --fix './src/**/*.{js,ts,svelte}' and it works perfectly.
Standalone Prettier
Here is my .prettierrc.js for running Prettier standalone:
module.exports = {
arrowParens: 'always',
singleQuote: true,
printWidth: 90,
plugins: ['prettier-plugin-svelte'],
semi: true,
svelteSortOrder: 'options-styles-scripts-markup',
svelteStrictMode: false,
svelteBracketNewLine: true,
svelteIndentScriptAndStyle: true,
trailingComma: 'none',
tabWidth: 4,
useTabs: true,
jsxBracketSameLine: false,
quoteProps: 'as-needed',
bracketSpacing: true,
endOfLine: 'lf'
}
I run it with prettier --write ./src and it works perfectly.
Combined ESLint & Prettier
My Prettier config remains the same, here is the modified ESLint config:
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:prettier/recommended'
],
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
extraFileExtensions: ['.svelte']
},
env: {
es6: true,
browser: true
},
overrides: [
{
files: ['*.svelte'],
processor: 'svelte3/svelte3'
}
],
settings: {
'svelte3/typescript': require('typescript'),
// ignore style tags in Svelte because of Tailwind CSS
// See https://github.com/sveltejs/eslint-plugin-svelte3/issues/70
'svelte3/ignore-styles': () => true
},
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['node_modules'],
rules: {
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
}
};
I run it with eslint --fix './src/**/*.{js,ts,svelte}' and it fails with this error:
2 | import Stats from "./components/Stats.svelte";
3 |
> 4 | {Board,Stats;}
| ^
The error is coming from a Svelte component and the import statements in it. Here is what those few lines in the Svelte component looks like. You'll notice that line 4 above doesn't actually exist in my source code:
<script lang="ts">
import Board from "./components/Board.svelte";
import Stats from "./components/Stats.svelte";
</script>
Conclusion
As best I can tell, by the time prettier parses the content it's in a form prettier cannot recognize. I'm wondering if there is a way to resolve this issue?
Thank you so much in advance.