From defa4d4c20a86581838c656a21aee3d042d02d09 Mon Sep 17 00:00:00 2001 From: Josh Creek <8179928+jcreek@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:58:06 +0000 Subject: [PATCH] chore(#2): Standardize eslint, prettier, and vscode lint settings --- .prettierrc | 2 +- .vscode/settings.json | 9 ++++++ eslint.config.js | 74 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.prettierrc b/.prettierrc index 7ebb855..dbb764e 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,7 +3,7 @@ "singleQuote": true, "trailingComma": "none", "printWidth": 100, - "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"], + "plugins": ["prettier-plugin-tailwindcss", "prettier-plugin-svelte"], "overrides": [ { "files": "*.svelte", diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4d650b9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "always" + }, + "eslint.useFlatConfig": true, + "eslint.validate": ["javascript", "typescript", "svelte"] +} diff --git a/eslint.config.js b/eslint.config.js index 9b34ef5..3a02127 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,37 +1,89 @@ -import prettier from 'eslint-config-prettier'; -import js from '@eslint/js'; import { includeIgnoreFile } from '@eslint/compat'; +import { FlatCompat } from '@eslint/eslintrc'; +import js from '@eslint/js'; +import prettier from 'eslint-config-prettier'; +import importPlugin from 'eslint-plugin-import'; import svelte from 'eslint-plugin-svelte'; import globals from 'globals'; +import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import ts from 'typescript-eslint'; +import tseslint from 'typescript-eslint'; import svelteConfig from './svelte.config.js'; const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url)); +const baseDirectory = path.dirname(fileURLToPath(import.meta.url)); +const compat = new FlatCompat({ + baseDirectory, + recommendedConfig: js.configs.recommended +}); -export default ts.config( +const airbnbBaseConfig = compat.extends('airbnb-base').map((config) => ({ + ...config, + files: ['**/*.{js,cjs,mjs,ts,cts,mts}'] +})); + +export default tseslint.config( includeIgnoreFile(gitignorePath), - js.configs.recommended, - ...ts.configs.recommended, - ...svelte.configs.recommended, + { + ignores: ['eslint.config.js', 'svelte.config.js', 'vite.config.ts'] + }, + { + plugins: { + import: importPlugin + } + }, + ...airbnbBaseConfig, + ...tseslint.configs.recommended, + ...svelte.configs['flat/recommended'], prettier, - ...svelte.configs.prettier, + ...svelte.configs['flat/prettier'], { languageOptions: { globals: { ...globals.browser, ...globals.node } }, - rules: { 'no-undef': 'off' } + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.mjs', '.cjs', '.ts', '.d.ts', '.svelte', '.json'] + } + }, + 'import/extensions': ['.js', '.ts', '.mjs', '.svelte'] + }, + rules: { + curly: ['error', 'all'], + 'brace-style': ['error', '1tbs', { allowSingleLine: false }], + 'no-continue': 'off', + 'no-restricted-syntax': 'off', + 'no-inner-declarations': 'off', + 'no-unused-vars': 'off', + 'import/no-extraneous-dependencies': 'off', + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + 'import/extensions': [ + 'error', + 'ignorePackages', + { + js: 'never', + mjs: 'never', + cjs: 'never', + ts: 'never' + } + ] + } }, { files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'], - ignores: ['eslint.config.js', 'svelte.config.js'], languageOptions: { parserOptions: { projectService: true, extraFileExtensions: ['.svelte'], - parser: ts.parser, + parser: tseslint.parser, svelteConfig } + }, + rules: { + // Svelte components commonly export mutable props and top-level declarations. + 'import/prefer-default-export': 'off', + 'import/no-mutable-exports': 'off' } } );