@vijayhardaha/dev-config 2.0.3 → 2.1.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 +20 -5
- package/package.json +54 -12
- package/src/eslint/lib/build-config.js +28 -5
- package/src/eslint/lib/build-config.test.js +40 -0
- package/src/jsconfig/index.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Reusable development configuration package for Next.js + TypeScript projects.
|
|
8
8
|
|
|
9
|
-
> **v2.0.
|
|
9
|
+
> **v2.0.4** — Requires ESLint >=10. Native flat config only. No FlatCompat.
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
@@ -21,17 +21,25 @@ Reusable development configuration package for Next.js + TypeScript projects.
|
|
|
21
21
|
## Installation
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
bun
|
|
24
|
+
bun add --dev @vijayhardaha/dev-config
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### Install Required Packages
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
bun add --dev eslint @eslint/compat prettier @prettier/plugin-xml eslint-plugin-prettier globals eslint-plugin-jsdoc eslint-plugin-import-x
|
|
30
|
+
bun add --dev eslint @eslint/compat eslint-config-prettier prettier @prettier/plugin-xml eslint-plugin-prettier globals eslint-plugin-jsdoc eslint-plugin-import-x @typescript-eslint/eslint-plugin @typescript-eslint/parser typescript typescript-eslint husky
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
### Install Optional Packages
|
|
34
34
|
|
|
35
|
+
Only install what you need based on your project setup.
|
|
36
|
+
|
|
37
|
+
#### TypeScript Import Resolution
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bun add --dev eslint-import-resolver-typescript
|
|
41
|
+
```
|
|
42
|
+
|
|
35
43
|
#### Stylelint
|
|
36
44
|
|
|
37
45
|
```bash
|
|
@@ -53,7 +61,7 @@ bun add --dev @next/eslint-plugin-next eslint-config-next
|
|
|
53
61
|
#### Commitlint
|
|
54
62
|
|
|
55
63
|
```bash
|
|
56
|
-
bun add --dev
|
|
64
|
+
bun add --dev @commitlint/cli @commitlint/config-conventional @commitlint/types
|
|
57
65
|
```
|
|
58
66
|
|
|
59
67
|
#### Next Sitemap
|
|
@@ -79,7 +87,14 @@ v2 drops FlatCompat and uses native ESLint 10 flat configs throughout.
|
|
|
79
87
|
|
|
80
88
|
1. Install ESLint 10+: `bun add --dev eslint@10`
|
|
81
89
|
2. Replace `eslint-plugin-import` with `eslint-plugin-import-x`
|
|
82
|
-
3. Remove unused deps: `@eslint/eslintrc`, `@eslint/js
|
|
90
|
+
3. Remove unused deps: `@eslint/eslintrc`, `@eslint/js`
|
|
91
|
+
|
|
92
|
+
### What's new in v2.0.4
|
|
93
|
+
|
|
94
|
+
- **`eslint-config-prettier` restored** — added back to peer deps (required by `eslint-plugin-prettier/recommended`)
|
|
95
|
+
- **`eslint-import-resolver-typescript` restored** — added back as optional peer for TypeScript import resolution
|
|
96
|
+
- **All packages declared as peer deps** — every config module's dependencies are declared with proper `peerDependenciesMeta`
|
|
97
|
+
- **Flat config resolver fix** — switched from string-based `import-x/resolver` to `import-x/resolver-next` with `createTypeScriptImportResolver` for ESLint 10 compatibility
|
|
83
98
|
|
|
84
99
|
## Quick Start
|
|
85
100
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vijayhardaha/dev-config",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Reusable development configurations for Next.js + TypeScript projects",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint": "eslint .",
|
|
@@ -68,32 +68,55 @@
|
|
|
68
68
|
"@commitlint/cli": "^21.0.2",
|
|
69
69
|
"@commitlint/config-conventional": "^21.0.2",
|
|
70
70
|
"@commitlint/types": "^21.0.1",
|
|
71
|
-
"@
|
|
72
|
-
"eslint-
|
|
71
|
+
"@typescript-eslint/parser": "^8.60.1",
|
|
72
|
+
"@typescript-eslint/eslint-plugin": "^8.60.1",
|
|
73
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
74
|
+
"eslint": "^10.4.1",
|
|
75
|
+
"eslint-config-next": "^16.2.7",
|
|
76
|
+
"eslint-config-prettier": "^10.1.8",
|
|
77
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
78
|
+
"eslint-plugin-jsdoc": "^63.0.1",
|
|
73
79
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
80
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
74
81
|
"eslint-plugin-react": "^7.37.5",
|
|
75
82
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
+
"globals": "^17.6.0",
|
|
84
|
+
"husky": "^9.1.7",
|
|
85
|
+
"prettier": "^3.8.3",
|
|
86
|
+
"@prettier/plugin-xml": "^3.4.2",
|
|
87
|
+
"release-it": "^20.2.0",
|
|
88
|
+
"typescript": "^6.0.3",
|
|
89
|
+
"typescript-eslint": "^8.60.1",
|
|
90
|
+
"vitest": "^4.1.8"
|
|
83
91
|
},
|
|
84
92
|
"peerDependencies": {
|
|
93
|
+
"@commitlint/cli": ">=21",
|
|
94
|
+
"@commitlint/config-conventional": ">=21",
|
|
95
|
+
"@commitlint/types": ">=21",
|
|
85
96
|
"@eslint/compat": ">=2",
|
|
97
|
+
"@next/eslint-plugin-next": ">=16",
|
|
86
98
|
"@prettier/plugin-xml": ">=3",
|
|
87
99
|
"@typescript-eslint/eslint-plugin": ">=8",
|
|
88
100
|
"@typescript-eslint/parser": ">=8",
|
|
89
101
|
"eslint": ">=10",
|
|
102
|
+
"eslint-config-next": ">=16",
|
|
103
|
+
"eslint-config-prettier": ">=10",
|
|
104
|
+
"eslint-import-resolver-typescript": ">=4",
|
|
90
105
|
"eslint-plugin-import-x": ">=4",
|
|
91
106
|
"eslint-plugin-jsdoc": ">=62",
|
|
107
|
+
"eslint-plugin-jsx-a11y": ">=6",
|
|
92
108
|
"eslint-plugin-prettier": ">=5",
|
|
109
|
+
"eslint-plugin-react": ">=7",
|
|
110
|
+
"eslint-plugin-react-hooks": ">=5",
|
|
93
111
|
"globals": ">=17",
|
|
94
112
|
"husky": ">=9",
|
|
95
|
-
"
|
|
96
|
-
"
|
|
113
|
+
"next-sitemap": ">=4",
|
|
114
|
+
"prettier": ">=3",
|
|
115
|
+
"stylelint": ">=17",
|
|
116
|
+
"stylelint-config-property-sort-order-smacss": ">=11",
|
|
117
|
+
"stylelint-config-standard-scss": ">=17",
|
|
118
|
+
"stylelint-order": ">=8",
|
|
119
|
+
"typescript": ">=5",
|
|
97
120
|
"typescript-eslint": ">=8"
|
|
98
121
|
},
|
|
99
122
|
"peerDependenciesMeta": {
|
|
@@ -109,9 +132,18 @@
|
|
|
109
132
|
"@next/eslint-plugin-next": {
|
|
110
133
|
"optional": true
|
|
111
134
|
},
|
|
135
|
+
"@typescript-eslint/eslint-plugin": {
|
|
136
|
+
"optional": true
|
|
137
|
+
},
|
|
138
|
+
"@typescript-eslint/parser": {
|
|
139
|
+
"optional": true
|
|
140
|
+
},
|
|
112
141
|
"eslint-config-next": {
|
|
113
142
|
"optional": true
|
|
114
143
|
},
|
|
144
|
+
"eslint-import-resolver-typescript": {
|
|
145
|
+
"optional": true
|
|
146
|
+
},
|
|
115
147
|
"eslint-plugin-jsx-a11y": {
|
|
116
148
|
"optional": true
|
|
117
149
|
},
|
|
@@ -121,6 +153,9 @@
|
|
|
121
153
|
"eslint-plugin-react-hooks": {
|
|
122
154
|
"optional": true
|
|
123
155
|
},
|
|
156
|
+
"husky": {
|
|
157
|
+
"optional": true
|
|
158
|
+
},
|
|
124
159
|
"next-sitemap": {
|
|
125
160
|
"optional": true
|
|
126
161
|
},
|
|
@@ -135,12 +170,19 @@
|
|
|
135
170
|
},
|
|
136
171
|
"stylelint-order": {
|
|
137
172
|
"optional": true
|
|
173
|
+
},
|
|
174
|
+
"typescript": {
|
|
175
|
+
"optional": true
|
|
176
|
+
},
|
|
177
|
+
"typescript-eslint": {
|
|
178
|
+
"optional": true
|
|
138
179
|
}
|
|
139
180
|
},
|
|
140
181
|
"overrides": {
|
|
141
182
|
"undici": "^7.0.0"
|
|
142
183
|
},
|
|
143
184
|
"trustedDependencies": [
|
|
185
|
+
"sharp",
|
|
144
186
|
"unrs-resolver"
|
|
145
187
|
]
|
|
146
188
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
1
4
|
import { fixupPluginRules } from '@eslint/compat';
|
|
2
|
-
import { defineConfig } from 'eslint/config';
|
|
3
|
-
import
|
|
5
|
+
import { defineConfig, includeIgnoreFile } from 'eslint/config';
|
|
6
|
+
import { createNodeResolver, flatConfigs as importXFlatConfigs } from 'eslint-plugin-import-x';
|
|
4
7
|
import jsdocPlugin from 'eslint-plugin-jsdoc';
|
|
5
8
|
import prettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
6
9
|
|
|
@@ -9,6 +12,13 @@ import { commonLanguageOptions } from './language-options.js';
|
|
|
9
12
|
import { commonRules } from './rules.js';
|
|
10
13
|
import { commonParser } from './setup.js';
|
|
11
14
|
|
|
15
|
+
let createTypeScriptImportResolver;
|
|
16
|
+
try {
|
|
17
|
+
createTypeScriptImportResolver = (await import('eslint-import-resolver-typescript')).createTypeScriptImportResolver;
|
|
18
|
+
} catch {
|
|
19
|
+
createTypeScriptImportResolver = null;
|
|
20
|
+
}
|
|
21
|
+
|
|
12
22
|
/**
|
|
13
23
|
* Filters conditional plugins based on user options.
|
|
14
24
|
*
|
|
@@ -166,7 +176,12 @@ const buildConfigObject = ({
|
|
|
166
176
|
...(typescript && { parserOptions: { tsconfigRootDir: process.cwd(), ...parserOptions } }),
|
|
167
177
|
},
|
|
168
178
|
settings: {
|
|
169
|
-
...(opts.importOrder && {
|
|
179
|
+
...(opts.importOrder && {
|
|
180
|
+
'import-x/resolver-next': [
|
|
181
|
+
createNodeResolver(),
|
|
182
|
+
...(createTypeScriptImportResolver ? [createTypeScriptImportResolver()] : []),
|
|
183
|
+
],
|
|
184
|
+
}),
|
|
170
185
|
...(opts.jsdoc && { jsdoc: { mode: 'typescript' } }),
|
|
171
186
|
...extraSettings,
|
|
172
187
|
...settings,
|
|
@@ -215,7 +230,7 @@ export const buildConfig = ({
|
|
|
215
230
|
|
|
216
231
|
const mergedPlugins = [
|
|
217
232
|
...builtinPlugins,
|
|
218
|
-
opts.importOrder &&
|
|
233
|
+
opts.importOrder && importXFlatConfigs.recommended,
|
|
219
234
|
opts.jsdoc && jsdocPlugin.configs['flat/recommended'],
|
|
220
235
|
opts.prettier && prettierRecommended,
|
|
221
236
|
...conditionalPluginList,
|
|
@@ -228,6 +243,9 @@ export const buildConfig = ({
|
|
|
228
243
|
const parsedConfigs = typescript ? stripParser(strippedConfigs) : strippedConfigs;
|
|
229
244
|
const mergedGlobalIgnores = mergeGlobalIgnores(opts.globalIgnores);
|
|
230
245
|
|
|
246
|
+
const gitignorePath = path.resolve(process.cwd(), '.gitignore');
|
|
247
|
+
const gitignoreConfig = existsSync(gitignorePath) ? includeIgnoreFile(gitignorePath) : null;
|
|
248
|
+
|
|
231
249
|
const configObject = buildConfigObject({
|
|
232
250
|
filePatterns,
|
|
233
251
|
opts,
|
|
@@ -239,5 +257,10 @@ export const buildConfig = ({
|
|
|
239
257
|
extraRules,
|
|
240
258
|
});
|
|
241
259
|
|
|
242
|
-
return defineConfig([
|
|
260
|
+
return defineConfig([
|
|
261
|
+
...mergedGlobalIgnores,
|
|
262
|
+
...(gitignoreConfig ? [gitignoreConfig] : []),
|
|
263
|
+
...parsedConfigs,
|
|
264
|
+
configObject,
|
|
265
|
+
]);
|
|
243
266
|
};
|
|
@@ -49,4 +49,44 @@ describe('eslint/lib/build-config.js', () => {
|
|
|
49
49
|
expect(configNames).toContain('test-flat-config');
|
|
50
50
|
expect(configNames).toContain('test-flat-object');
|
|
51
51
|
});
|
|
52
|
+
|
|
53
|
+
// Test that buildConfig sets import-x/resolver-next when importOrder is enabled.
|
|
54
|
+
it('should configure import-x/resolver-next with node resolver when importOrder is enabled', async () => {
|
|
55
|
+
const module = await import('./build-config.js');
|
|
56
|
+
const { files } = await import('./files.js');
|
|
57
|
+
|
|
58
|
+
const result = module.buildConfig({ files: files.withoutTs, options: { importOrder: true } });
|
|
59
|
+
|
|
60
|
+
// The last config object in the array should have the resolver settings
|
|
61
|
+
const configObject = result[result.length - 1];
|
|
62
|
+
expect(configObject.settings).toBeDefined();
|
|
63
|
+
expect(configObject.settings['import-x/resolver-next']).toBeDefined();
|
|
64
|
+
expect(Array.isArray(configObject.settings['import-x/resolver-next'])).toBe(true);
|
|
65
|
+
// Should at least have the node resolver
|
|
66
|
+
expect(configObject.settings['import-x/resolver-next'].length).toBeGreaterThanOrEqual(1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Test that buildConfig omits import-x/resolver-next when importOrder is disabled.
|
|
70
|
+
it('should omit import-x/resolver-next when importOrder is disabled', async () => {
|
|
71
|
+
const module = await import('./build-config.js');
|
|
72
|
+
const { files } = await import('./files.js');
|
|
73
|
+
|
|
74
|
+
const result = module.buildConfig({ files: files.withoutTs, options: { importOrder: false } });
|
|
75
|
+
|
|
76
|
+
const configObject = result[result.length - 1];
|
|
77
|
+
expect(configObject.settings).toBeDefined();
|
|
78
|
+
expect(configObject.settings['import-x/resolver-next']).toBeUndefined();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Test that buildConfig includes .gitignore patterns via includeIgnoreFile.
|
|
82
|
+
it('should include .gitignore patterns from project root', async () => {
|
|
83
|
+
const module = await import('./build-config.js');
|
|
84
|
+
const { files } = await import('./files.js');
|
|
85
|
+
|
|
86
|
+
const result = module.buildConfig({ files: files.withoutTs, options: {} });
|
|
87
|
+
|
|
88
|
+
// When .gitignore exists at the project root, includeIgnoreFile adds a config with ignores.
|
|
89
|
+
const hasIgnoreConfig = result.some((config) => config.ignores && config.ignores.length > 0);
|
|
90
|
+
expect(hasIgnoreConfig).toBe(true);
|
|
91
|
+
});
|
|
52
92
|
});
|
package/src/jsconfig/index.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"compilerOptions": { "jsx": "react-jsx", "resolveJsonModule": true, "
|
|
2
|
+
"compilerOptions": { "jsx": "react-jsx", "resolveJsonModule": true, "paths": { "@/*": ["./src/*"] } },
|
|
3
3
|
"exclude": ["node_modules", ".next", "out"]
|
|
4
4
|
}
|