@st1ggy/linter-config 2.41.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1,71 @@
1
- # linter-config
1
+ # @st1ggy/linter-config
2
+
3
+ Shared ESLint, Prettier and Stylelint configs for React, Next.js and Svelte projects.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm i -D @st1ggy/linter-config
9
+ ```
10
+
11
+ Install only toolchain dependencies you actually use in your project (`eslint`, `prettier`, `stylelint`, framework packages).
12
+
13
+ This package targets **ESLint 9–10**, **Prettier 3**, and **Stylelint 17**. Install matching majors in the consuming repo.
14
+
15
+ ### Migration (Stylelint)
16
+
17
+ If you previously used Stylelint 16 with this preset, upgrade the consumer to **Stylelint 17** before depending on the latest release.
18
+
19
+ ### Development of this package
20
+
21
+ When working on this repository, `npm install` uses [`.npmrc`](.npmrc) `legacy-peer-deps=true` because `eslint-import-resolver-custom-alias` still declares a peer on `eslint-plugin-import@>=2`, so npm may pull the legacy import plugin for resolution even though published presets use **eslint-plugin-import-x**. Consumer projects that only install `@st1ggy/linter-config` are unaffected.
22
+
23
+ ## Toolchain (this repo)
24
+
25
+ Single entry points for all linters:
26
+
27
+ ```bash
28
+ npm run lint # eslint → stylelint → prettier --check
29
+ npm run lint:fix # eslint --fix → stylelint --fix → prettier --write
30
+ ```
31
+
32
+ Individual steps: `npm run lint:eslint`, `npm run lint:stylelint`, `npm run lint:prettier`.
33
+
34
+ In your application you can mirror the same pattern (sequential or parallel with `npm-run-all` / `concurrently`).
35
+
36
+ ## Tree-shaking friendly imports
37
+
38
+ Prefer **subpath** imports so only the preset you need is loaded (smaller static import graph for Node and bundlers). The package is published with `sideEffects: false` and explicit `exports` per subpath.
39
+
40
+ ```js
41
+ import eslintReact from '@st1ggy/linter-config/eslint-react'
42
+ import prettierCommon from '@st1ggy/linter-config/prettier-common'
43
+ import stylelintScss from '@st1ggy/linter-config/stylelint-scss'
44
+ ```
45
+
46
+ The root entry re-exports every preset from one module; it is convenient but pulls the combined graph:
47
+
48
+ ```js
49
+ import { eslintReact } from '@st1ggy/linter-config'
50
+ ```
51
+
52
+ Use the root import only when you intentionally want that barrel.
53
+
54
+ ## Optional rule packs (not included by default)
55
+
56
+ These are common next steps for stricter or more consistent code; add them in your own `eslint.config` if you need them:
57
+
58
+ - **eslint-plugin-n** — Node.js-specific imports and `package.json` `exports` / `node:` protocol.
59
+ - **eslint-plugin-jsx-a11y** — accessibility rules for React.
60
+ - **eslint-plugin-perfectionist** — opinionated sorting (can overlap with import order / stylistic rules).
61
+ - **typescript-eslint** `recommendedTypeChecked` — stricter type-aware rules (higher cost and stricter `tsconfig` requirements).
62
+
63
+ ## Available Configs
64
+
65
+ - `@st1ggy/linter-config/eslint-common`
66
+ - `@st1ggy/linter-config/eslint-react`
67
+ - `@st1ggy/linter-config/eslint-next`
68
+ - `@st1ggy/linter-config/eslint-svelte`
69
+ - `@st1ggy/linter-config/prettier-common`
70
+ - `@st1ggy/linter-config/prettier-svelte`
71
+ - `@st1ggy/linter-config/stylelint-scss`
package/index.d.ts CHANGED
@@ -1,7 +1,21 @@
1
- import { type ConfigArray } from 'eslint'
1
+ import { type Linter } from 'eslint'
2
2
  import { type Config as PrettierConfig } from 'prettier'
3
3
  import { type Config as StylelintConfig } from 'stylelint'
4
4
 
5
+ type ConfigArray = Linter.Config[]
6
+
7
+ declare module '@st1ggy/linter-config' {
8
+ export const eslintCommon: ConfigArray
9
+ export const eslintReact: ConfigArray
10
+ export const eslintNext: ConfigArray
11
+ export const eslintSvelte: ConfigArray
12
+
13
+ export const prettierCommon: PrettierConfig
14
+ export const prettierSvelte: PrettierConfig
15
+
16
+ export const stylelintScss: StylelintConfig
17
+ }
18
+
5
19
  declare module '@st1ggy/linter-config/eslint-next' {
6
20
  const config: ConfigArray
7
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@st1ggy/linter-config",
3
- "version": "2.41.0",
3
+ "version": "3.0.0",
4
4
  "description": "ESLint, Stylelint and Prettier configs for React, Vue [WIP] and Svelte [WIP]",
5
5
  "private": false,
6
6
  "repository": {
@@ -19,48 +19,79 @@
19
19
  },
20
20
  "homepage": "https://github.com/St1ggy/linter-config#readme",
21
21
  "dependencies": {
22
- "@eslint/compat": "^1.4.1",
23
- "@eslint/js": "^9.39.0",
24
- "@stylistic/eslint-plugin": "^5.5.0",
25
- "@stylistic/eslint-plugin-migrate": "^4.4.1",
26
- "eslint": "^9.39.0",
27
- "eslint-config-next": "^16.0.1",
22
+ "@next/eslint-plugin-next": "^16.2.3",
23
+ "@eslint/compat": "^2.0.5",
24
+ "@eslint/js": "^10.0.1",
25
+ "@stylistic/eslint-plugin": "^5.10.0",
26
+ "eslint": "^10.2.0",
28
27
  "eslint-config-prettier": "^10.1.8",
29
28
  "eslint-import-resolver-custom-alias": "^1.3.2",
30
29
  "eslint-import-resolver-typescript": "^4.4.4",
31
- "eslint-plugin-import": "^2.32.0",
32
- "eslint-plugin-prettier": "^5.5.4",
30
+ "eslint-plugin-import-x": "^4.16.2",
31
+ "eslint-plugin-prettier": "^5.5.5",
33
32
  "eslint-plugin-react": "^7.37.5",
34
33
  "eslint-plugin-react-hooks": "^7.0.1",
35
- "eslint-plugin-sonarjs": "^3.0.5",
36
- "eslint-plugin-svelte": "^3.13.0",
37
- "eslint-plugin-unicorn": "^62.0.0",
34
+ "eslint-plugin-sonarjs": "^4.0.2",
35
+ "eslint-plugin-svelte": "^3.17.0",
36
+ "eslint-plugin-unicorn": "^64.0.0",
38
37
  "find-up-simple": "^1.0.1",
39
- "patch-package": "^8.0.1",
40
- "prettier": "^3.6.2",
41
- "prettier-plugin-svelte": "^3.4.0",
42
- "stylelint": "^16.25.0",
43
- "stylelint-config-clean-order": "^7.0.0",
44
- "stylelint-config-prettier": "^9.0.5",
45
- "stylelint-config-recommended": "^17.0.0",
46
- "stylelint-config-recommended-scss": "^16.0.2",
47
- "stylelint-config-sass-guidelines": "^12.1.0",
48
- "stylelint-no-unsupported-browser-features": "^8.0.5",
49
- "stylelint-order": "^7.0.0",
38
+ "prettier": "^3.8.2",
39
+ "prettier-plugin-svelte": "^3.5.1",
40
+ "stylelint": "^17.6.0",
41
+ "stylelint-config-clean-order": "^8.0.1",
42
+ "stylelint-config-recommended": "^18.0.0",
43
+ "stylelint-config-recommended-scss": "^17.0.1",
44
+ "stylelint-config-sass-guidelines": "^13.0.0",
45
+ "stylelint-no-unsupported-browser-features": "^8.1.1",
46
+ "stylelint-order": "^8.1.1",
50
47
  "stylelint-prettier": "^5.0.3",
51
- "typescript": "^5.9.3",
52
- "typescript-eslint": "^8.46.2"
48
+ "typescript": "^6.0.2",
49
+ "typescript-eslint": "^8.58.1"
53
50
  },
51
+ "types": "./index.d.ts",
54
52
  "type": "module",
53
+ "sideEffects": false,
55
54
  "exports": {
56
- ".": "./src/index.js",
57
- "./eslint-next": "./src/eslint/eslint.config.next.js",
58
- "./eslint-react": "./src/eslint/eslint.config.react.js",
59
- "./eslint-svelte": "./src/eslint/eslint.config.svelte.js",
60
- "./eslint-common": "./src/eslint/eslint.config.common.js",
61
- "./prettier-common": "./src/prettier/prettier.config.common.js",
62
- "./prettier-svelte": "./src/prettier/prettier.config.svelte.js",
63
- "./stylelint-scss": "./src/stylelint/stylelint.config.scss.js"
55
+ ".": {
56
+ "types": "./index.d.ts",
57
+ "import": "./src/index.js",
58
+ "default": "./src/index.js"
59
+ },
60
+ "./eslint-next": {
61
+ "types": "./index.d.ts",
62
+ "import": "./src/eslint/eslint.config.next.js",
63
+ "default": "./src/eslint/eslint.config.next.js"
64
+ },
65
+ "./eslint-react": {
66
+ "types": "./index.d.ts",
67
+ "import": "./src/eslint/eslint.config.react.js",
68
+ "default": "./src/eslint/eslint.config.react.js"
69
+ },
70
+ "./eslint-svelte": {
71
+ "types": "./index.d.ts",
72
+ "import": "./src/eslint/eslint.config.svelte.js",
73
+ "default": "./src/eslint/eslint.config.svelte.js"
74
+ },
75
+ "./eslint-common": {
76
+ "types": "./index.d.ts",
77
+ "import": "./src/eslint/eslint.config.common.js",
78
+ "default": "./src/eslint/eslint.config.common.js"
79
+ },
80
+ "./prettier-common": {
81
+ "types": "./index.d.ts",
82
+ "import": "./src/prettier/prettier.config.common.js",
83
+ "default": "./src/prettier/prettier.config.common.js"
84
+ },
85
+ "./prettier-svelte": {
86
+ "types": "./index.d.ts",
87
+ "import": "./src/prettier/prettier.config.svelte.js",
88
+ "default": "./src/prettier/prettier.config.svelte.js"
89
+ },
90
+ "./stylelint-scss": {
91
+ "types": "./index.d.ts",
92
+ "import": "./src/stylelint/stylelint.config.scss.js",
93
+ "default": "./src/stylelint/stylelint.config.scss.js"
94
+ }
64
95
  },
65
96
  "files": [
66
97
  "src",
@@ -68,11 +99,41 @@
68
99
  "index.d.ts"
69
100
  ],
70
101
  "scripts": {
71
- "lint": "eslint .",
72
- "lint:fix": "eslint . --fix"
102
+ "lint:eslint": "eslint .",
103
+ "lint:stylelint": "stylelint \"**/*.{css,scss}\" --config ./src/stylelint/stylelint.config.scss.js --allow-empty-input",
104
+ "lint:prettier": "prettier --check .",
105
+ "lint": "npm run lint:eslint && npm run lint:stylelint && npm run lint:prettier",
106
+ "lint:fix": "eslint . --fix && stylelint \"**/*.{css,scss}\" --config ./src/stylelint/stylelint.config.scss.js --fix --allow-empty-input && prettier --write ."
73
107
  },
74
108
  "peerDependencies": {
75
- "react": "^19.0.0",
76
- "svelte": "^5.23.0"
109
+ "eslint": "^9.0.0 || ^10.0.0",
110
+ "next": "^16.0.0",
111
+ "prettier": "^3.0.0",
112
+ "react": "^18.0.0 || ^19.0.0",
113
+ "stylelint": "^17.0.0",
114
+ "svelte": "^4.0.0 || ^5.0.0"
115
+ },
116
+ "devDependencies": {
117
+ "@stylistic/eslint-plugin-migrate": "^4.4.1"
118
+ },
119
+ "peerDependenciesMeta": {
120
+ "eslint": {
121
+ "optional": true
122
+ },
123
+ "next": {
124
+ "optional": true
125
+ },
126
+ "prettier": {
127
+ "optional": true
128
+ },
129
+ "react": {
130
+ "optional": true
131
+ },
132
+ "stylelint": {
133
+ "optional": true
134
+ },
135
+ "svelte": {
136
+ "optional": true
137
+ }
77
138
  }
78
139
  }
@@ -6,4 +6,6 @@ import { fileURLToPath } from 'node:url'
6
6
 
7
7
  const gitignorePath = findUpSync('.gitignore', { cwd: process.cwd() })
8
8
 
9
- export default defineConfig([includeIgnoreFile(fileURLToPath(new URL(gitignorePath, import.meta.url)))])
9
+ export default defineConfig(
10
+ gitignorePath ? [includeIgnoreFile(fileURLToPath(new URL(gitignorePath, import.meta.url)))] : [],
11
+ )
@@ -1,16 +1,16 @@
1
1
  import { defineConfig } from 'eslint/config'
2
- import importPlugin from 'eslint-plugin-import'
2
+ import { flatConfigs } from 'eslint-plugin-import-x'
3
3
 
4
4
  import { files } from './constants.js'
5
5
 
6
6
  export default defineConfig([
7
- importPlugin.flatConfigs.recommended,
8
- importPlugin.flatConfigs.typescript,
7
+ flatConfigs.recommended,
8
+ flatConfigs.typescript,
9
9
  {
10
10
  files,
11
11
  rules: {
12
- 'import/newline-after-import': 'error',
13
- 'import/order': [
12
+ 'import-x/newline-after-import': 'error',
13
+ 'import-x/order': [
14
14
  'error',
15
15
  {
16
16
  'newlines-between': 'always',
@@ -28,14 +28,14 @@ export default defineConfig([
28
28
  },
29
29
  },
30
30
  ],
31
- 'import/no-duplicates': [
31
+ 'import-x/no-duplicates': [
32
32
  'error',
33
33
  {
34
34
  considerQueryString: true,
35
35
  },
36
36
  ],
37
- 'import/prefer-default-export': 'off',
38
- 'import/extensions': [
37
+ 'import-x/prefer-default-export': 'off',
38
+ 'import-x/extensions': [
39
39
  'error',
40
40
  'never',
41
41
  {
@@ -43,10 +43,10 @@ export default defineConfig([
43
43
  json: 'ignorePackages',
44
44
  },
45
45
  ],
46
- 'import/no-unresolved': ['error', {}],
46
+ 'import-x/no-unresolved': ['error', {}],
47
47
  },
48
48
  settings: {
49
- 'import/resolver': {
49
+ 'import-x/resolver': {
50
50
  typescript: true,
51
51
  node: true,
52
52
  },
@@ -1,8 +1,11 @@
1
+ /* eslint-disable import-x/no-named-as-default-member -- @next/eslint-plugin-next is CJS; no ESM named export for configs */
1
2
  import nextPlugin from '@next/eslint-plugin-next'
2
3
  import { defineConfig } from 'eslint/config'
3
4
 
4
5
  import { files } from './constants.js'
5
6
 
7
+ const { configs: nextConfigs } = nextPlugin
8
+
6
9
  export default defineConfig([
7
10
  {
8
11
  files,
@@ -10,8 +13,8 @@ export default defineConfig([
10
13
  '@next/next': nextPlugin,
11
14
  },
12
15
  rules: {
13
- ...nextPlugin.configs.recommended.rules,
14
- ...nextPlugin.configs['core-web-vitals'].rules,
16
+ ...nextConfigs.recommended.rules,
17
+ ...nextConfigs['core-web-vitals'].rules,
15
18
  },
16
19
  },
17
20
  ])
@@ -1,4 +1,3 @@
1
- import stylistic from '@stylistic/eslint-plugin'
2
1
  import { defineConfig } from 'eslint/config'
3
2
  import reactPlugin from 'eslint-plugin-react'
4
3
  import reactHooksPlugin from 'eslint-plugin-react-hooks'
@@ -8,7 +7,6 @@ import { files } from './constants.js'
8
7
  export default defineConfig([
9
8
  reactPlugin.configs.flat.recommended,
10
9
  reactPlugin.configs.flat['jsx-runtime'],
11
- stylistic.configs.recommended,
12
10
  {
13
11
  files,
14
12
  plugins: { 'react-hooks': reactHooksPlugin },
@@ -11,8 +11,8 @@ export default defineConfig([
11
11
  {
12
12
  files,
13
13
  rules: {
14
- 'import/named': 'off',
15
- 'import/no-cycle': 'off',
14
+ 'import-x/named': 'off',
15
+ 'import-x/no-cycle': 'off',
16
16
  },
17
17
  languageOptions: {
18
18
  parserOptions: {
@@ -23,11 +23,11 @@ export default defineConfig([
23
23
  },
24
24
  },
25
25
  settings: {
26
- // 'import/parsers': {
26
+ // 'import-x/parsers': {
27
27
  // 'svelte-eslint-parser': ['.svelte'],
28
28
  // espree: extensions,
29
29
  // },
30
- 'import/resolver': {
30
+ 'import-x/resolver': {
31
31
  'eslint-import-resolver-custom-alias': {
32
32
  alias: {
33
33
  $lib: 'src/lib',
@@ -1,4 +1,4 @@
1
- import nextConfig from './eslint.config.next.js'
1
+ import nextConfig from './configs/config.next.js'
2
2
  import reactConfig from './eslint.config.react.js'
3
3
 
4
4
  export default [...reactConfig, ...nextConfig]
@@ -1 +1 @@
1
- export {}
1
+ export const example = true
package/scripts/patch.sh DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- npx patch-package --patch-dir "$(dirname "$0")/../patches"