From b5a7df3703221e63024b5bafda7a776f6d6977b2 Mon Sep 17 00:00:00 2001 From: Garfield Lee Date: Sat, 4 Jan 2025 04:16:21 +0800 Subject: [PATCH] feat: strict limitations on the scope of files to which the rules apply (#20) --- packages/eslint-config/src/configs/imports.ts | 5 +++ .../eslint-config/src/configs/javascript.ts | 4 +++ packages/eslint-config/src/configs/json.ts | 2 +- packages/eslint-config/src/configs/next-js.ts | 2 +- packages/eslint-config/src/configs/node-js.ts | 2 +- packages/eslint-config/src/configs/react.ts | 2 +- packages/eslint-config/src/configs/regexp.ts | 4 +++ .../eslint-config/src/configs/tailwindcss.ts | 4 +++ .../eslint-config/src/configs/typescript.ts | 2 +- packages/eslint-config/src/configs/unicorn.ts | 32 +++++++++++++++---- packages/eslint-config/src/globs.ts | 9 ++++-- 11 files changed, 54 insertions(+), 14 deletions(-) diff --git a/packages/eslint-config/src/configs/imports.ts b/packages/eslint-config/src/configs/imports.ts index 8eaf30d..cfbc4b3 100644 --- a/packages/eslint-config/src/configs/imports.ts +++ b/packages/eslint-config/src/configs/imports.ts @@ -4,10 +4,12 @@ import process from 'node:process' import type { OptionsTypeScript } from '../options.js' import type { TypedFlatConfigItem } from '../types.js' +import { GLOB_SRC } from '../globs.js' import plugins from '../plugins.js' import { getFlatConfigName } from '../utils/index.js' const name = getFlatConfigName('imports') +const files: string[] = [GLOB_SRC] export function imports(options: OptionsTypeScript = {}): TypedFlatConfigItem[] { const { @@ -17,6 +19,7 @@ export function imports(options: OptionsTypeScript = {}): TypedFlatConfigItem[] return [ { name: name.setup, + files, plugins: { 'import-x': plugins['pluginImportX'], 'unused-imports': plugins['pluginUnusedImports'], @@ -30,6 +33,7 @@ export function imports(options: OptionsTypeScript = {}): TypedFlatConfigItem[] }, { name: name.rules, + files, rules: { // eslint-plugin-import-x // https://github.com/un-ts/eslint-plugin-import-x @@ -59,6 +63,7 @@ export function imports(options: OptionsTypeScript = {}): TypedFlatConfigItem[] }, { name: name.stylistic, + files, rules: { // rules that conflict with eslint-plugin-perfectionist are disabled. 'sort-imports': 'off', diff --git a/packages/eslint-config/src/configs/javascript.ts b/packages/eslint-config/src/configs/javascript.ts index a15fe7d..9b488ff 100644 --- a/packages/eslint-config/src/configs/javascript.ts +++ b/packages/eslint-config/src/configs/javascript.ts @@ -6,10 +6,12 @@ import globals from 'globals' import type { OptionsJavaScript } from '../options.js' import type { TypedFlatConfigItem } from '../types.js' +import { GLOB_SRC } from '../globs.js' import plugins from '../plugins.js' import { getFlatConfigName } from '../utils/index.js' const name = getFlatConfigName('javascript') +const files: string[] = [GLOB_SRC] const commonjsGlobalsOffList = Object.keys(globals.commonjs).map< Record @@ -27,6 +29,7 @@ export function javascript(options: OptionsJavaScript = {}): TypedFlatConfigItem return [ { name: name.setup, + files, plugins: { 'import-x': plugins['pluginImportX'], 'unused-imports': plugins['pluginUnusedImports'], @@ -80,6 +83,7 @@ export function javascript(options: OptionsJavaScript = {}): TypedFlatConfigItem }, { name: name.rules, + files, rules: { ...js.configs.recommended.rules, diff --git a/packages/eslint-config/src/configs/json.ts b/packages/eslint-config/src/configs/json.ts index 432e515..cd52da4 100644 --- a/packages/eslint-config/src/configs/json.ts +++ b/packages/eslint-config/src/configs/json.ts @@ -27,7 +27,7 @@ export function json(options: OptionsJson = {}): TypedFlatConfigItem[] { ? stylistic : ({ indentWidth: 2 } as const) - const files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC, ...extraFiles] + const files: string[] = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC, ...extraFiles] return [ { diff --git a/packages/eslint-config/src/configs/next-js.ts b/packages/eslint-config/src/configs/next-js.ts index b5541a3..f61d0be 100644 --- a/packages/eslint-config/src/configs/next-js.ts +++ b/packages/eslint-config/src/configs/next-js.ts @@ -8,7 +8,7 @@ import plugins from '../plugins.js' import { getFlatConfigName } from '../utils/index.js' const name = getFlatConfigName('next-js') -const files = [GLOB_SRC] +const files: string[] = [GLOB_SRC] export function nextJs(): TypedFlatConfigItem[] { return [ diff --git a/packages/eslint-config/src/configs/node-js.ts b/packages/eslint-config/src/configs/node-js.ts index 342923c..a8512c1 100644 --- a/packages/eslint-config/src/configs/node-js.ts +++ b/packages/eslint-config/src/configs/node-js.ts @@ -13,7 +13,7 @@ const isModule = getPackageJson()?.type === 'module' export function nodeJs(options: OptionsNodeJs = {}): TypedFlatConfigItem[] { const { module = isModule, extraFiles = [] } = options - const files = [GLOB_JS, ...extraFiles] + const files: string[] = [GLOB_JS, ...extraFiles] return [ { diff --git a/packages/eslint-config/src/configs/react.ts b/packages/eslint-config/src/configs/react.ts index ae956d1..b343ef4 100644 --- a/packages/eslint-config/src/configs/react.ts +++ b/packages/eslint-config/src/configs/react.ts @@ -8,7 +8,7 @@ import plugins from '../plugins.js' import { getFlatConfigName } from '../utils/index.js' const name = getFlatConfigName('react') -const files = [GLOB_SRC] +const files: string[] = [GLOB_SRC] export function react(options: OptionsReact = {}): TypedFlatConfigItem[] { const { stylistic = true, reactCompiler = false } = options diff --git a/packages/eslint-config/src/configs/regexp.ts b/packages/eslint-config/src/configs/regexp.ts index abf85f6..ab96c3f 100644 --- a/packages/eslint-config/src/configs/regexp.ts +++ b/packages/eslint-config/src/configs/regexp.ts @@ -2,21 +2,25 @@ import * as pluginRegexp from 'eslint-plugin-regexp' import type { TypedFlatConfigItem } from '../types.js' +import { GLOB_SRC } from '../globs.js' import plugins from '../plugins.js' import { getFlatConfigName } from '../utils/index.js' const name = getFlatConfigName('regexp') +const files: string[] = [GLOB_SRC] export function regexp(): TypedFlatConfigItem[] { return [ { name: name.setup, + files, plugins: { regexp: plugins['pluginRegexp'], }, }, { name: name.rules, + files, rules: { // eslint-plugin-regexp // https://github.com/ota-meshi/eslint-plugin-regexp diff --git a/packages/eslint-config/src/configs/tailwindcss.ts b/packages/eslint-config/src/configs/tailwindcss.ts index 559c9a7..6299b67 100644 --- a/packages/eslint-config/src/configs/tailwindcss.ts +++ b/packages/eslint-config/src/configs/tailwindcss.ts @@ -1,14 +1,17 @@ import type { TypedFlatConfigItem } from '../types.js' +import { GLOB_HTML, GLOB_POSTCSS, GLOB_SRC, GLOB_STYLE } from '../globs.js' import plugins from '../plugins.js' import { getFlatConfigName } from '../utils/index.js' const name = getFlatConfigName('tailwindcss') +const files: string[] = [GLOB_SRC, GLOB_STYLE, GLOB_POSTCSS, GLOB_HTML] export function tailwindcss(): TypedFlatConfigItem[] { return [ { name: name.setup, + files, plugins: { tailwindcss: plugins['pluginTailwindCSS'], }, @@ -20,6 +23,7 @@ export function tailwindcss(): TypedFlatConfigItem[] { }, { name: name.rules, + files, rules: { // eslint-plugin-tailwindcss // https://github.com/francoismassart/eslint-plugin-tailwindcss diff --git a/packages/eslint-config/src/configs/typescript.ts b/packages/eslint-config/src/configs/typescript.ts index 2388f6d..db86850 100644 --- a/packages/eslint-config/src/configs/typescript.ts +++ b/packages/eslint-config/src/configs/typescript.ts @@ -41,7 +41,7 @@ export function typescript(options: OptionsTypeScript = {}): TypedFlatConfigItem reactTypeCheck = false, } = options - const files = [ + const files: string[] = [ GLOB_TS, GLOB_TSX, ...extraFileExtensions.map((extension) => `**/*${extension}`), diff --git a/packages/eslint-config/src/configs/unicorn.ts b/packages/eslint-config/src/configs/unicorn.ts index 16fd712..e1adf23 100644 --- a/packages/eslint-config/src/configs/unicorn.ts +++ b/packages/eslint-config/src/configs/unicorn.ts @@ -3,18 +3,26 @@ import globals from 'globals' import type { TypedFlatConfigItem } from '../types.js' +import { GLOB_ALL_SRC, GLOB_SRC } from '../globs.js' import plugins from '../plugins.js' import { getFlatConfigName } from '../utils/index.js' const name = getFlatConfigName('unicorn') +const files: string[] = [GLOB_SRC] +const allFiles: string[] = [...GLOB_ALL_SRC] export function unicorn(): TypedFlatConfigItem[] { return [ { - name: name.setup, + name: `${name.setup}/all-src`, + files: allFiles, plugins: { unicorn: plugins['pluginUnicorn'], }, + }, + { + name: `${name.setup}/src`, + files, languageOptions: { globals: { ...globals.builtin, @@ -22,18 +30,28 @@ export function unicorn(): TypedFlatConfigItem[] { }, }, { - name: name.rules, + name: `${name.rules}/all-src`, + files: allFiles, rules: { - // eslint-plugin-unicorn - // https://github.com/sindresorhus/eslint-plugin-unicorn - ...pluginUnicorn.configs['flat/recommended'].rules, - - // Ignore case for specific files + // Let all files use kebab-case for filenames. + // kebab-case forces filenames to be lowercase and hyphen-separated, + // some file systems are case-insensitive, so this rule can help prevent + // issues with importing files on case-sensitive file systems. 'unicorn/filename-case': ['error', { cases: { kebabCase: true }, + // Ignore case for specific files ignore: ['README.md', 'LICENSE.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md'], }], }, }, + { + name: `${name.rules}/src`, + files, + rules: { + // eslint-plugin-unicorn + // https://github.com/sindresorhus/eslint-plugin-unicorn + ...pluginUnicorn.configs['flat/recommended'].rules, + }, + }, ] } diff --git a/packages/eslint-config/src/globs.ts b/packages/eslint-config/src/globs.ts index 80183ad..c41a52e 100644 --- a/packages/eslint-config/src/globs.ts +++ b/packages/eslint-config/src/globs.ts @@ -14,9 +14,9 @@ export const GLOB_TSX = '**/*.?([cm])tsx' export const GLOB_STYLE = '**/*.{c,le,sc}ss' export const GLOB_CSS = '**/*.css' -export const GLOB_POSTCSS = '**/*.{p,post}css' export const GLOB_LESS = '**/*.less' export const GLOB_SCSS = '**/*.scss' +export const GLOB_POSTCSS = '**/*.{p,post}css' export const GLOB_JSON = '**/*.json' export const GLOB_JSON5 = '**/*.json5' @@ -29,8 +29,8 @@ export const GLOB_VUE = '**/*.vue' export const GLOB_YAML = '**/*.y?(a)ml' export const GLOB_TOML = '**/*.toml' export const GLOB_XML = '**/*.xml' -export const GLOB_SVG = '**/*.svg' export const GLOB_HTML = '**/*.htm?(l)' +export const GLOB_SVG = '**/*.svg' export const GLOB_ASTRO = '**/*.astro' export const GLOB_ASTRO_TS = '**/*.astro/*.ts' export const GLOB_GRAPHQL = '**/*.{g,graph}ql' @@ -48,14 +48,19 @@ export const GLOB_TESTS = [ export const GLOB_ALL_SRC = [ GLOB_SRC, GLOB_STYLE, + GLOB_POSTCSS, GLOB_JSON, GLOB_JSON5, + GLOB_JSONC, GLOB_MARKDOWN, GLOB_SVELTE, GLOB_VUE, GLOB_YAML, + GLOB_TOML, GLOB_XML, GLOB_HTML, + GLOB_SVG, + GLOB_ASTRO, ] export const GLOB_EXCLUDE = [