@fullstacksjs/eslint-config 11.8.0 → 11.9.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 +25 -46
- package/cjs/index.js +6 -2
- package/cjs/modules/imports.js +9 -18
- package/package.json +1 -2
- package/src/index.mjs +6 -3
- package/src/modules/imports.mjs +9 -21
package/README.md
CHANGED
|
@@ -18,27 +18,27 @@ $ npm install --save-dev @fullstacksjs/eslint-config eslint prettier
|
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
|
-
To use the configuration, all you need is to export the generated config by the `
|
|
21
|
+
To use the configuration, all you need is to export the generated config by the `defineConfig` function. The configuration reads the metadata from your root `package.json` file and automatically adds the rules and plugins that are needed.
|
|
22
22
|
|
|
23
23
|
### ESM
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
|
-
import {
|
|
26
|
+
import { defineConfig } from '@fullstacksjs/eslint-config';
|
|
27
27
|
|
|
28
|
-
export default
|
|
28
|
+
export default defineConfig();
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
### CJS
|
|
32
32
|
|
|
33
33
|
```js
|
|
34
|
-
const {
|
|
34
|
+
const { defineConfig } = require('@fullstacksjs/eslint-config');
|
|
35
35
|
|
|
36
|
-
module.exports =
|
|
36
|
+
module.exports = defineConfig();
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
## Modules API
|
|
40
40
|
|
|
41
|
-
You can fine-tune module detection by overriding it, the `
|
|
41
|
+
You can fine-tune module detection by overriding it, the `defineConfig` function accepts options as its first argument to control enabled modules.
|
|
42
42
|
|
|
43
43
|
```typescript
|
|
44
44
|
interface Options {
|
|
@@ -71,12 +71,12 @@ interface Options {
|
|
|
71
71
|
|
|
72
72
|
## Extra configuration
|
|
73
73
|
|
|
74
|
-
You can pass any number of arbitrary custom config overrides to `
|
|
74
|
+
You can pass any number of arbitrary custom config overrides to `defineConfig` function:
|
|
75
75
|
|
|
76
76
|
```js
|
|
77
|
-
import {
|
|
77
|
+
import { defineConfig } from '@fullstacksjs/eslint-config';
|
|
78
78
|
|
|
79
|
-
export default
|
|
79
|
+
export default defineConfig(
|
|
80
80
|
{
|
|
81
81
|
typescript: true,
|
|
82
82
|
// You can pass extends here
|
|
@@ -93,6 +93,12 @@ export default init(
|
|
|
93
93
|
})
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
+
## Next.JS Warning
|
|
97
|
+
|
|
98
|
+
**Question**: I'm getting "The Next.js plugin was not detected in your ESLint" warning.
|
|
99
|
+
|
|
100
|
+
**Answer**: This plugin has built-in support for Next.js. The warning from Next.js is misleading—Next.js simply checks `package.json` to see if the plugin is listed. You can safely ignore the warning or update your lint script from `next lint` to `eslint`.
|
|
101
|
+
|
|
96
102
|
## Speed Optimization!
|
|
97
103
|
|
|
98
104
|
Balancing the benefits of linting rules against their performance impact is crucial. Below is a table highlighting the most resource-intensive linting rules encountered in a real-world React project:
|
|
@@ -110,20 +116,20 @@ To conditionally disable expensive linting rules, you can modify your configurat
|
|
|
110
116
|
|
|
111
117
|
List of `expensiveRules` to be affected:
|
|
112
118
|
|
|
113
|
-
```
|
|
119
|
+
```sh
|
|
114
120
|
@typescript-eslint/no-floating-promises
|
|
115
121
|
@typescript-eslint/no-misused-promises
|
|
116
|
-
import/default
|
|
117
|
-
import/export
|
|
118
|
-
import/named
|
|
122
|
+
import/default # (disabled in TS env)
|
|
123
|
+
import/export # (disabled in TS env)
|
|
124
|
+
import/named # (disabled in TS env)
|
|
125
|
+
import/no-named-as-default-member # (disabled in TS env)
|
|
119
126
|
import/namespace
|
|
120
127
|
import/no-cycle
|
|
121
128
|
import/no-deprecated
|
|
122
|
-
import/no-named-as-default-member
|
|
123
129
|
```
|
|
124
130
|
|
|
125
131
|
```js
|
|
126
|
-
export default
|
|
132
|
+
export default defineConfig({
|
|
127
133
|
disableExpensiveRules: !process.env.CI || !process.env.HUSKY // Or anywhere you want
|
|
128
134
|
prettier: false // So you should run the formatter explicitly.
|
|
129
135
|
});
|
|
@@ -131,49 +137,22 @@ export default init({
|
|
|
131
137
|
|
|
132
138
|
## Migration Guide
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
v11 drops support for ESLint v8 configuration and only ESLint v9 is supported, which means you should migrate to [ESlint Flat Config](https://eslint.org/docs/latest/extend/plugin-migration-flat-config):
|
|
137
|
-
|
|
138
|
-
1. Move your configs to `eslint.config.js` file.
|
|
139
|
-
2. Use init API.
|
|
140
|
-
```diff
|
|
141
|
-
-const { init } = require('@fullstacksjs/eslint-config/init');
|
|
142
|
-
+import { init } from '@fullstacksjs/eslint-config';
|
|
143
|
-
|
|
144
|
-
-module.exports = init({
|
|
145
|
-
- modules: {
|
|
146
|
-
- auto: true,
|
|
147
|
-
- esm: true,
|
|
148
|
-
- typescript: {
|
|
149
|
-
- parserProject: ['./tsconfig.eslint.json'],
|
|
150
|
-
- resolverProject: ['./tsconfig.json'],
|
|
151
|
-
- },
|
|
152
|
-
- },
|
|
153
|
-
- // your configuration
|
|
154
|
-
-});
|
|
155
|
-
+export default init({
|
|
156
|
-
+ esm: true,
|
|
157
|
-
+ typescript: true,
|
|
158
|
-
+ },
|
|
159
|
-
+ // your configuration
|
|
160
|
-
+);
|
|
161
|
-
```
|
|
140
|
+
[See Migration Guide](./MIGRATION.md)
|
|
162
141
|
|
|
163
142
|
## What's included?
|
|
164
143
|
|
|
165
144
|
* [@eslint-react/eslint-plugin](https://eslint-react.xyz/)
|
|
166
|
-
* [@next/eslint-
|
|
145
|
+
* [@next/eslint-plugin-next](https://nextjs.org/docs/basic-features/eslint#eslint-plugin)
|
|
146
|
+
* [@stylistic/eslint-plugin](https://eslint.style/packages/default)
|
|
167
147
|
* [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress)
|
|
168
148
|
* [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x)
|
|
169
149
|
* [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest)
|
|
170
150
|
* [eslint-plugin-jest-formatting](https://github.com/dangreenisrael/eslint-plugin-jest-formatting)
|
|
171
151
|
* [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)
|
|
172
|
-
* [eslint-plugin-perfectionist](https://perfectionist.dev/)
|
|
173
152
|
* [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n)
|
|
153
|
+
* [eslint-plugin-perfectionist](https://perfectionist.dev/)
|
|
174
154
|
* [eslint-plugin-playwright](https://github.com/playwright-community/eslint-plugin-playwright)
|
|
175
155
|
* [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)
|
|
176
|
-
* [eslint-plugin-perfectionist](https://perfectionist.dev/)
|
|
177
156
|
* [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise)
|
|
178
157
|
* [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)
|
|
179
158
|
* [eslint-plugin-storybook](https://github.com/storybookjs/eslint-plugin-storybook#readme)
|
package/cjs/index.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.defineConfig = defineConfig;
|
|
7
|
+
exports.init = void 0;
|
|
7
8
|
var _deepmerge = _interopRequireDefault(require("deepmerge"));
|
|
8
9
|
var _config = require("eslint/config");
|
|
9
10
|
var _localPkg = require("local-pkg");
|
|
@@ -62,7 +63,7 @@ const defaultOptions = {
|
|
|
62
63
|
* @param {...Config} extend
|
|
63
64
|
* @returns {Config[]}
|
|
64
65
|
*/
|
|
65
|
-
function
|
|
66
|
+
function defineConfig(initOptions = {}, ...extend) {
|
|
66
67
|
const options = (0, _deepmerge.default)(defaultOptions, initOptions);
|
|
67
68
|
if (options.tailwind === true) {
|
|
68
69
|
options.tailwind = {};
|
|
@@ -113,3 +114,6 @@ function init(initOptions = {}, ...extend) {
|
|
|
113
114
|
if (extend) Array.prototype.push.apply(rules, extend);
|
|
114
115
|
return (0, _config.defineConfig)(rules);
|
|
115
116
|
}
|
|
117
|
+
|
|
118
|
+
/** @deprecated Please use `defineConfig` from `@fullstacksjs/eslint-config` instead, this function will be removed in the next major release */
|
|
119
|
+
const init = exports.init = defineConfig;
|
package/cjs/modules/imports.js
CHANGED
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
|
|
7
|
-
var _eslintImportResolverTypescript = require("eslint-import-resolver-typescript");
|
|
8
7
|
var _eslintPluginImportX = _interopRequireDefault(require("eslint-plugin-import-x"));
|
|
9
8
|
var _conditions = require("../utils/conditions.js");
|
|
10
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -18,28 +17,14 @@ const allExtensions = [...jsExtensions, ...tsExtensions];
|
|
|
18
17
|
*/
|
|
19
18
|
function imports(options = {}) {
|
|
20
19
|
const isObject = typeof options.import === 'object';
|
|
21
|
-
const ignoreExtensions = {};
|
|
22
|
-
if (!options.esm) {
|
|
23
|
-
ignoreExtensions.js = 'never';
|
|
24
|
-
ignoreExtensions.jsx = 'never';
|
|
25
|
-
if (options.typescript) {
|
|
26
|
-
ignoreExtensions.ts = 'never';
|
|
27
|
-
ignoreExtensions.tsx = 'never';
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
20
|
const config = {
|
|
31
21
|
plugins: {
|
|
32
22
|
import: _eslintPluginImportX.default
|
|
33
23
|
},
|
|
34
24
|
settings: {
|
|
35
25
|
'import-x/extensions': jsExtensions,
|
|
36
|
-
'import-x/
|
|
37
|
-
'import-x/ignore': ['node_modules', '\\.(scss|css|svg|json)$'],
|
|
26
|
+
'import-x/ignore': ['node_modules', '\\.(scss|css|svg|json|mdx)$'],
|
|
38
27
|
...(0, _conditions.predicate)(options.typescript, {
|
|
39
|
-
'import-x/resolver-next': [(0, _eslintImportResolverTypescript.createTypeScriptImportResolver)({
|
|
40
|
-
alwaysTryTypes: true,
|
|
41
|
-
project: options.typescript.projects
|
|
42
|
-
})],
|
|
43
28
|
'import-x/parsers': {
|
|
44
29
|
'@typescript-eslint/parser': tsExtensions
|
|
45
30
|
},
|
|
@@ -56,7 +41,7 @@ function imports(options = {}) {
|
|
|
56
41
|
},
|
|
57
42
|
rules: {
|
|
58
43
|
'import/consistent-type-specifier-style': ['warn', 'prefer-top-level'],
|
|
59
|
-
'import/extensions': ['error', 'ignorePackages',
|
|
44
|
+
// 'import/extensions': ['error', 'ignorePackages', ignorePackages: true, js: opt, jsx: opt, mjs: opt, cjs: opt, ...(options.typescript && { ts: opt, tsx: opt, mts: opt, cts: opt, }), ], FIXME: This rule is broken!
|
|
60
45
|
'import/first': 'error',
|
|
61
46
|
'import/newline-after-import': 'warn',
|
|
62
47
|
'import/no-absolute-path': 'error',
|
|
@@ -106,7 +91,13 @@ function imports(options = {}) {
|
|
|
106
91
|
'import/no-unassigned-import': 'off',
|
|
107
92
|
'import/no-unused-modules': 'off',
|
|
108
93
|
'import/prefer-default-export': 'off',
|
|
109
|
-
'import/unambiguous': 'off'
|
|
94
|
+
'import/unambiguous': 'off',
|
|
95
|
+
...(0, _conditions.predicate)(options.typescript, {
|
|
96
|
+
'import/default': 'off',
|
|
97
|
+
'import/named': 'off',
|
|
98
|
+
'import/no-named-as-default-member': 'off',
|
|
99
|
+
'import/no-unresolved': 'off'
|
|
100
|
+
})
|
|
110
101
|
}
|
|
111
102
|
};
|
|
112
103
|
return config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fullstacksjs/eslint-config",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "fullstacks <fullstacksjs@gmail.com>",
|
|
6
6
|
"description": "fullstacks eslint config",
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"@next/eslint-plugin-next": "15.1.7",
|
|
39
39
|
"@stylistic/eslint-plugin": "4.1.0",
|
|
40
40
|
"deepmerge": "4.3.1",
|
|
41
|
-
"eslint-import-resolver-typescript": "4.2.2",
|
|
42
41
|
"eslint-plugin-cypress": "4.1.0",
|
|
43
42
|
"eslint-plugin-import-x": "4.6.1",
|
|
44
43
|
"eslint-plugin-jest": "28.11.0",
|
package/src/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import merge from 'deepmerge';
|
|
2
|
-
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import { defineConfig as eslintConfig } from 'eslint/config';
|
|
3
3
|
import { isPackageExists } from 'local-pkg';
|
|
4
4
|
|
|
5
5
|
import base from './modules/base.mjs';
|
|
@@ -55,7 +55,7 @@ const defaultOptions = {
|
|
|
55
55
|
* @param {...Config} extend
|
|
56
56
|
* @returns {Config[]}
|
|
57
57
|
*/
|
|
58
|
-
export function
|
|
58
|
+
export function defineConfig(initOptions = {}, ...extend) {
|
|
59
59
|
const options = merge(defaultOptions, initOptions);
|
|
60
60
|
|
|
61
61
|
if (options.tailwind === true) {
|
|
@@ -110,5 +110,8 @@ export function init(initOptions = {}, ...extend) {
|
|
|
110
110
|
if (Object.keys(eslintOptions).length > 0) rules.push(eslintOptions);
|
|
111
111
|
if (extend) Array.prototype.push.apply(rules, extend);
|
|
112
112
|
|
|
113
|
-
return
|
|
113
|
+
return eslintConfig(rules);
|
|
114
114
|
}
|
|
115
|
+
|
|
116
|
+
/** @deprecated Please use `defineConfig` from `@fullstacksjs/eslint-config` instead, this function will be removed in the next major release */
|
|
117
|
+
export const init = defineConfig;
|
package/src/modules/imports.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
|
|
2
1
|
import plugin from 'eslint-plugin-import-x';
|
|
3
2
|
|
|
4
3
|
import { predicate } from '../utils/conditions.mjs';
|
|
@@ -13,31 +12,13 @@ const allExtensions = [...jsExtensions, ...tsExtensions];
|
|
|
13
12
|
*/
|
|
14
13
|
function imports(options = {}) {
|
|
15
14
|
const isObject = typeof options.import === 'object';
|
|
16
|
-
const ignoreExtensions = {};
|
|
17
|
-
if (!options.esm) {
|
|
18
|
-
ignoreExtensions.js = 'never';
|
|
19
|
-
ignoreExtensions.jsx = 'never';
|
|
20
|
-
|
|
21
|
-
if (options.typescript) {
|
|
22
|
-
ignoreExtensions.ts = 'never';
|
|
23
|
-
ignoreExtensions.tsx = 'never';
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
15
|
|
|
27
16
|
const config = {
|
|
28
17
|
plugins: { import: plugin },
|
|
29
|
-
|
|
30
18
|
settings: {
|
|
31
19
|
'import-x/extensions': jsExtensions,
|
|
32
|
-
'import-x/
|
|
33
|
-
'import-x/ignore': ['node_modules', '\\.(scss|css|svg|json)$'],
|
|
20
|
+
'import-x/ignore': ['node_modules', '\\.(scss|css|svg|json|mdx)$'],
|
|
34
21
|
...predicate(options.typescript, {
|
|
35
|
-
'import-x/resolver-next': [
|
|
36
|
-
createTypeScriptImportResolver({
|
|
37
|
-
alwaysTryTypes: true,
|
|
38
|
-
project: options.typescript.projects,
|
|
39
|
-
}),
|
|
40
|
-
],
|
|
41
22
|
'import-x/parsers': { '@typescript-eslint/parser': tsExtensions },
|
|
42
23
|
'import-x/extensions': allExtensions,
|
|
43
24
|
}),
|
|
@@ -51,7 +32,7 @@ function imports(options = {}) {
|
|
|
51
32
|
|
|
52
33
|
rules: {
|
|
53
34
|
'import/consistent-type-specifier-style': ['warn', 'prefer-top-level'],
|
|
54
|
-
'import/extensions': ['error', 'ignorePackages',
|
|
35
|
+
// 'import/extensions': ['error', 'ignorePackages', ignorePackages: true, js: opt, jsx: opt, mjs: opt, cjs: opt, ...(options.typescript && { ts: opt, tsx: opt, mts: opt, cts: opt, }), ], FIXME: This rule is broken!
|
|
55
36
|
'import/first': 'error',
|
|
56
37
|
'import/newline-after-import': 'warn',
|
|
57
38
|
'import/no-absolute-path': 'error',
|
|
@@ -98,6 +79,13 @@ function imports(options = {}) {
|
|
|
98
79
|
'import/no-unused-modules': 'off',
|
|
99
80
|
'import/prefer-default-export': 'off',
|
|
100
81
|
'import/unambiguous': 'off',
|
|
82
|
+
|
|
83
|
+
...predicate(options.typescript, {
|
|
84
|
+
'import/default': 'off',
|
|
85
|
+
'import/named': 'off',
|
|
86
|
+
'import/no-named-as-default-member': 'off',
|
|
87
|
+
'import/no-unresolved': 'off',
|
|
88
|
+
}),
|
|
101
89
|
},
|
|
102
90
|
};
|
|
103
91
|
|