eslint-config-webpack 4.9.4 → 4.9.6
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/configs/javascript.js +14 -3
- package/configs/markdown.js +1 -0
- package/configs/node.js +48 -4
- package/configs/utils/get-es-version-from-node.js +83 -0
- package/configs.js +49 -65
- package/package.json +17 -17
package/configs/javascript.js
CHANGED
|
@@ -690,6 +690,8 @@ const unicornRules = {
|
|
|
690
690
|
// No need
|
|
691
691
|
// "unicorn/consistent-function-scoping": "off",
|
|
692
692
|
|
|
693
|
+
"unicorn/consistent-template-literal-escape": "error",
|
|
694
|
+
|
|
693
695
|
// No need
|
|
694
696
|
// "unicorn/custom-error-definition": "off",
|
|
695
697
|
|
|
@@ -706,7 +708,7 @@ const unicornRules = {
|
|
|
706
708
|
// No need
|
|
707
709
|
// "unicorn/explicit-length-check": "off",
|
|
708
710
|
|
|
709
|
-
// TODO
|
|
711
|
+
// TODO enable in future?
|
|
710
712
|
"unicorn/filename-case": [
|
|
711
713
|
"off",
|
|
712
714
|
{
|
|
@@ -834,7 +836,7 @@ const unicornRules = {
|
|
|
834
836
|
// No need
|
|
835
837
|
// "unicorn/no-this-assignment": "off",
|
|
836
838
|
|
|
837
|
-
// TODO
|
|
839
|
+
// TODO enable in future? Need to check performance
|
|
838
840
|
// "unicorn/no-typeof-undefined": "off",
|
|
839
841
|
|
|
840
842
|
"unicorn/no-unnecessary-array-flat-depth": "error",
|
|
@@ -862,6 +864,8 @@ const unicornRules = {
|
|
|
862
864
|
|
|
863
865
|
"unicorn/no-useless-fallback-in-spread": "error",
|
|
864
866
|
|
|
867
|
+
"unicorn/no-useless-iterator-to-array": "error",
|
|
868
|
+
|
|
865
869
|
"unicorn/no-useless-length-check": "error",
|
|
866
870
|
|
|
867
871
|
"unicorn/no-useless-promise-resolve-reject": "error",
|
|
@@ -993,6 +997,9 @@ const unicornRules = {
|
|
|
993
997
|
// No need
|
|
994
998
|
// "unicorn/prefer-set-size": "off",
|
|
995
999
|
|
|
1000
|
+
// TODO enable in the next major release
|
|
1001
|
+
// "unicorn/prefer-simple-condition-first": "error",
|
|
1002
|
+
|
|
996
1003
|
// No need
|
|
997
1004
|
// "unicorn/prefer-single-call": "off",
|
|
998
1005
|
|
|
@@ -1045,6 +1052,10 @@ const unicornRules = {
|
|
|
1045
1052
|
// No need
|
|
1046
1053
|
// "unicorn/switch-case-braces": "off",
|
|
1047
1054
|
|
|
1055
|
+
// TODO maybe?
|
|
1056
|
+
// No need
|
|
1057
|
+
// "unicorn/switch-case-break-position": "off",
|
|
1058
|
+
|
|
1048
1059
|
// No need
|
|
1049
1060
|
// "unicorn/template-indent": "off",
|
|
1050
1061
|
|
|
@@ -1230,7 +1241,7 @@ const baseConfig = {
|
|
|
1230
1241
|
import: importPlugin,
|
|
1231
1242
|
},
|
|
1232
1243
|
linterOptions: {
|
|
1233
|
-
reportUnusedDisableDirectives:
|
|
1244
|
+
reportUnusedDisableDirectives: "error",
|
|
1234
1245
|
reportUnusedInlineConfigs: "error",
|
|
1235
1246
|
},
|
|
1236
1247
|
rules: {
|
package/configs/markdown.js
CHANGED
package/configs/node.js
CHANGED
|
@@ -73,8 +73,7 @@ const commonRules = {
|
|
|
73
73
|
// No need
|
|
74
74
|
// "n/no-top-level-await": "error",
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
// "n/no-unpublished-bin": "error",
|
|
76
|
+
"n/no-unpublished-bin": "error",
|
|
78
77
|
|
|
79
78
|
// From recommended
|
|
80
79
|
// "n/no-unpublished-import": "error",
|
|
@@ -95,8 +94,53 @@ const commonRules = {
|
|
|
95
94
|
|
|
96
95
|
// "n/no-unsupported-features/es-syntax": "error",
|
|
97
96
|
|
|
98
|
-
// From recommended
|
|
99
|
-
|
|
97
|
+
// From recommended (override to ignore test module)
|
|
98
|
+
"n/no-unsupported-features/node-builtins": [
|
|
99
|
+
"error",
|
|
100
|
+
{
|
|
101
|
+
ignores: [
|
|
102
|
+
"test",
|
|
103
|
+
"test.after",
|
|
104
|
+
"test.afterEach",
|
|
105
|
+
"test.assert",
|
|
106
|
+
"test.assert.register",
|
|
107
|
+
"test.before",
|
|
108
|
+
"test.beforeEach",
|
|
109
|
+
"test.describe",
|
|
110
|
+
"test.describe.only",
|
|
111
|
+
"test.describe.skip",
|
|
112
|
+
"test.describe.todo",
|
|
113
|
+
"test.it",
|
|
114
|
+
"test.it.only",
|
|
115
|
+
"test.it.skip",
|
|
116
|
+
"test.it.todo",
|
|
117
|
+
"test.mock",
|
|
118
|
+
"test.mock.fn",
|
|
119
|
+
"test.mock.getter",
|
|
120
|
+
"test.mock.method",
|
|
121
|
+
"test.mock.module",
|
|
122
|
+
"test.mock.reset",
|
|
123
|
+
"test.mock.restoreAll",
|
|
124
|
+
"test.mock.setter",
|
|
125
|
+
"test.mock.timers",
|
|
126
|
+
"test.mock.timers.enable",
|
|
127
|
+
"test.mock.timers.reset",
|
|
128
|
+
"test.mock.timers.tick",
|
|
129
|
+
"test.only",
|
|
130
|
+
"test.run",
|
|
131
|
+
"test.snapshot",
|
|
132
|
+
"test.snapshot.setDefaultSnapshotSerializers",
|
|
133
|
+
"test.snapshot.setResolveSnapshotPath",
|
|
134
|
+
"test.skip",
|
|
135
|
+
"test.suite",
|
|
136
|
+
"test.test",
|
|
137
|
+
"test.test.only",
|
|
138
|
+
"test.test.skip",
|
|
139
|
+
"test.test.todo",
|
|
140
|
+
"test.todo",
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
],
|
|
100
144
|
|
|
101
145
|
"n/prefer-global/buffer": ["error", "always"],
|
|
102
146
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import semver from "semver";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025} EsVersion
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Ordered table from Node version ranges to the highest ES version every
|
|
9
|
+
* release in the range fully supports.
|
|
10
|
+
*
|
|
11
|
+
* The table respects minor versions where they shift the supported feature
|
|
12
|
+
* set, e.g. async/await landed in Node 7.6 (ES2017), and `Object.hasOwn`
|
|
13
|
+
* landed in Node 16.11 (ES2022) — the last ES2022 feature to ship on the
|
|
14
|
+
* Node 16 line.
|
|
15
|
+
*
|
|
16
|
+
* Sources: https://node.green/ and the Node.js/V8 release notes. Entries
|
|
17
|
+
* are sorted newest-to-oldest; the first matching entry wins.
|
|
18
|
+
* @type {ReadonlyArray<{ range: string, esVersion: EsVersion }>}
|
|
19
|
+
*/
|
|
20
|
+
const ranges = [
|
|
21
|
+
// ES2025: Node 22.0 ships all ES2025 syntax — import attributes
|
|
22
|
+
// (`with { type: "json" }`), the RegExp `/v` flag, and duplicate named
|
|
23
|
+
// capturing groups. Stdlib gaps (e.g. Promise.try lands at 22.5) are
|
|
24
|
+
// caught by eslint-plugin-n's `no-unsupported-features/node-builtins`,
|
|
25
|
+
// so we don't need a separate ES2024 row here.
|
|
26
|
+
{ range: ">=22.0.0", esVersion: 2025 },
|
|
27
|
+
// ES2023: Array-by-copy (toSorted/toReversed/toSpliced/with), findLast/findLastIndex.
|
|
28
|
+
{ range: ">=20.0.0", esVersion: 2023 },
|
|
29
|
+
// ES2022: Object.hasOwn is the last ES2022 feature to land on the Node 16 line.
|
|
30
|
+
// Earlier 16.x has top-level await (>=14.8), `.at()` (>=16.6) and Error cause (>=16.9)
|
|
31
|
+
// but not Object.hasOwn, so it can't safely claim full ES2022.
|
|
32
|
+
{ range: ">=16.11.0", esVersion: 2022 },
|
|
33
|
+
// ES2021: logical assignment operators, String#replaceAll, Promise.any, WeakRef.
|
|
34
|
+
{ range: ">=15.0.0", esVersion: 2021 },
|
|
35
|
+
// ES2020: optional chaining, nullish coalescing, BigInt, Promise.allSettled, globalThis.
|
|
36
|
+
{ range: ">=14.0.0", esVersion: 2020 },
|
|
37
|
+
// ES2019: Object.fromEntries, Array#flat/flatMap, String#trimStart/trimEnd.
|
|
38
|
+
{ range: ">=12.0.0", esVersion: 2019 },
|
|
39
|
+
// ES2018: object rest/spread, async iteration, RegExp lookbehind, Promise#finally.
|
|
40
|
+
{ range: ">=10.0.0", esVersion: 2018 },
|
|
41
|
+
// ES2017: async/await is the gating feature — landed in 7.6, not 7.0.
|
|
42
|
+
{ range: ">=7.6.0", esVersion: 2017 },
|
|
43
|
+
// ES2016: ** exponentiation operator and Array#includes (both require >=7.0).
|
|
44
|
+
{ range: ">=7.0.0", esVersion: 2016 },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Resolves the highest ES version every Node release matched by
|
|
49
|
+
* `nodeRange` fully supports.
|
|
50
|
+
*
|
|
51
|
+
* Returns `undefined` when the lower bound is older than our oldest entry
|
|
52
|
+
* (Node 7.0), so callers can apply project-specific fallbacks — for example
|
|
53
|
+
* Node 6, which has `Array#includes` (from 6.5) but never gained the `**`
|
|
54
|
+
* operator and so doesn't map cleanly to a single ES year.
|
|
55
|
+
* @param {string} nodeRange a semver range, typically `package.json#engines.node`
|
|
56
|
+
* @returns {EsVersion | undefined} matching ES version, or `undefined`
|
|
57
|
+
*/
|
|
58
|
+
function getEsVersionFromNode(nodeRange) {
|
|
59
|
+
// `semver.minVersion` throws on unparseable input. Guard against a
|
|
60
|
+
// malformed `engines.node` so loading the ESLint config never crashes
|
|
61
|
+
// the consuming project — we just fall back to the caller's default.
|
|
62
|
+
let minVersion;
|
|
63
|
+
try {
|
|
64
|
+
minVersion = semver.minVersion(nodeRange);
|
|
65
|
+
// eslint-disable-next-line unicorn/prefer-optional-catch-binding
|
|
66
|
+
} catch (_err) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!minVersion) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (const { range, esVersion } of ranges) {
|
|
75
|
+
if (semver.satisfies(minVersion, range)) {
|
|
76
|
+
return esVersion;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default getEsVersionFromNode;
|
package/configs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { globalIgnores } from "eslint/config";
|
|
2
2
|
import semver from "semver";
|
|
3
3
|
import configs from "./configs/index.js";
|
|
4
|
+
import getEsVersionFromNode from "./configs/utils/get-es-version-from-node.js";
|
|
4
5
|
import getJsonFile from "./configs/utils/get-json-file.js";
|
|
5
6
|
import ignorePaths from "./ignore-paths.js";
|
|
6
7
|
|
|
@@ -15,73 +16,56 @@ const isModule =
|
|
|
15
16
|
* @returns {import("eslint").Linter.Config} javascript configuration
|
|
16
17
|
*/
|
|
17
18
|
function getJavascriptConfig() {
|
|
18
|
-
if (packageJson.engines
|
|
19
|
-
|
|
20
|
-
const minMajorVersion = minVersion ? minVersion.major : undefined;
|
|
21
|
-
|
|
22
|
-
// https://node.green/
|
|
23
|
-
// https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping
|
|
24
|
-
switch (minMajorVersion) {
|
|
25
|
-
case 6: {
|
|
26
|
-
const config = {
|
|
27
|
-
...configs["javascript/es2016"],
|
|
28
|
-
rules: { ...configs["javascript/es2016"].rules },
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
config.rules["prefer-exponentiation-operator"] = "off";
|
|
32
|
-
|
|
33
|
-
return config;
|
|
34
|
-
}
|
|
35
|
-
case 7:
|
|
36
|
-
return configs["javascript/es2016"];
|
|
37
|
-
case 8:
|
|
38
|
-
case 9:
|
|
39
|
-
return configs["javascript/es2017"];
|
|
40
|
-
case 10:
|
|
41
|
-
case 11:
|
|
42
|
-
return configs["javascript/es2018"];
|
|
43
|
-
case 12:
|
|
44
|
-
case 13: {
|
|
45
|
-
/** @type {import("eslint").Linter.Config["languageOptions"]} */
|
|
46
|
-
const original = configs["javascript/es2019"].languageOptions;
|
|
47
|
-
/** @type {import("eslint").Linter.Config["languageOptions"]} */
|
|
48
|
-
const languageOptions = {
|
|
49
|
-
...original,
|
|
50
|
-
globals: {
|
|
51
|
-
// @ts-expect-error always exist
|
|
52
|
-
...original.globals,
|
|
53
|
-
Promise: false,
|
|
54
|
-
BigInt: false,
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
return { ...configs["javascript/es2019"], languageOptions };
|
|
59
|
-
}
|
|
60
|
-
case 14:
|
|
61
|
-
return configs["javascript/es2020"];
|
|
62
|
-
|
|
63
|
-
case 15:
|
|
64
|
-
return configs["javascript/es2021"];
|
|
65
|
-
case 16:
|
|
66
|
-
case 17:
|
|
67
|
-
case 18:
|
|
68
|
-
case 19:
|
|
69
|
-
return configs["javascript/es2022"];
|
|
70
|
-
case 20:
|
|
71
|
-
case 21:
|
|
72
|
-
return configs["javascript/es2023"];
|
|
73
|
-
case 22:
|
|
74
|
-
case 23:
|
|
75
|
-
return configs["javascript/es2024"];
|
|
76
|
-
case 24:
|
|
77
|
-
case 25:
|
|
78
|
-
return configs["javascript/es2025"];
|
|
79
|
-
default:
|
|
80
|
-
return configs["javascript/recommended"];
|
|
81
|
-
}
|
|
19
|
+
if (!packageJson.engines || !packageJson.engines.node) {
|
|
20
|
+
return configs["javascript/recommended"];
|
|
82
21
|
}
|
|
83
22
|
|
|
84
|
-
|
|
23
|
+
const nodeRange = packageJson.engines.node;
|
|
24
|
+
const minVersion = semver.minVersion(nodeRange);
|
|
25
|
+
|
|
26
|
+
// Node 6 has Array#includes (from 6.5) but never gained the `**` operator,
|
|
27
|
+
// so it doesn't map cleanly to a single ES year — handle it inline.
|
|
28
|
+
// https://node.green/
|
|
29
|
+
if (minVersion && minVersion.major === 6) {
|
|
30
|
+
const base = configs["javascript/es2016"];
|
|
31
|
+
return {
|
|
32
|
+
...base,
|
|
33
|
+
rules: {
|
|
34
|
+
...base.rules,
|
|
35
|
+
"prefer-exponentiation-operator": "off",
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const esVersion = getEsVersionFromNode(nodeRange);
|
|
41
|
+
|
|
42
|
+
if (esVersion === undefined) {
|
|
43
|
+
return configs["javascript/recommended"];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const config = configs[`javascript/es${esVersion}`];
|
|
47
|
+
|
|
48
|
+
// The `globals.es2019` set from the `globals` package doesn't declare
|
|
49
|
+
// `Promise` or `BigInt`, but both are available at runtime on Node 12+.
|
|
50
|
+
// Re-add them as readonly globals so `no-undef` doesn't flag usage.
|
|
51
|
+
if (esVersion === 2019) {
|
|
52
|
+
/** @type {import("eslint").Linter.Config["languageOptions"]} */
|
|
53
|
+
const original = config.languageOptions;
|
|
54
|
+
/** @type {import("eslint").Linter.Config["languageOptions"]} */
|
|
55
|
+
const languageOptions = {
|
|
56
|
+
...original,
|
|
57
|
+
globals: {
|
|
58
|
+
// @ts-expect-error always exist
|
|
59
|
+
...original.globals,
|
|
60
|
+
Promise: false,
|
|
61
|
+
BigInt: false,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return { ...config, languageOptions };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return config;
|
|
85
69
|
}
|
|
86
70
|
|
|
87
71
|
const javascriptConfig = getJavascriptConfig();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-config-webpack",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.6",
|
|
4
4
|
"description": "Provides Webpack's eslint rules as an extensible shared config",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -40,36 +40,36 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@eslint/js": "^9.39.2",
|
|
43
|
-
"@eslint/markdown": "^
|
|
43
|
+
"@eslint/markdown": "^8.0.1",
|
|
44
44
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
45
45
|
"detect-indent": "^7.0.2",
|
|
46
46
|
"eslint-config-prettier": "^10.1.8",
|
|
47
47
|
"eslint-plugin-import": "^2.32.0",
|
|
48
|
-
"eslint-plugin-jest": "^29.15.
|
|
49
|
-
"eslint-plugin-jsdoc": "^62.
|
|
50
|
-
"eslint-plugin-n": "^
|
|
48
|
+
"eslint-plugin-jest": "^29.15.2",
|
|
49
|
+
"eslint-plugin-jsdoc": "^62.9.0",
|
|
50
|
+
"eslint-plugin-n": "^18.0.1",
|
|
51
51
|
"eslint-plugin-prettier": "^5.5.5",
|
|
52
52
|
"eslint-plugin-react": "^7.37.5",
|
|
53
|
-
"eslint-plugin-react-hooks": "^7.
|
|
54
|
-
"eslint-plugin-unicorn": "^
|
|
55
|
-
"globals": "^17.
|
|
53
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
54
|
+
"eslint-plugin-unicorn": "^64.0.0",
|
|
55
|
+
"globals": "^17.6.0",
|
|
56
56
|
"jsonc-eslint-parser": "^3.1.0",
|
|
57
|
-
"semver": "^7.
|
|
57
|
+
"semver": "^7.8.0",
|
|
58
58
|
"sort-package-json": "^3.6.0",
|
|
59
|
-
"typescript-eslint": "^8.
|
|
59
|
+
"typescript-eslint": "^8.59.3"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@changesets/cli": "^2.
|
|
62
|
+
"@changesets/cli": "^2.31.0",
|
|
63
63
|
"@changesets/get-github-info": "^0.8.0",
|
|
64
64
|
"@types/semver": "^7.7.1",
|
|
65
65
|
"eslint": "^9.39.2",
|
|
66
66
|
"eslint-find-rules": "^5.0.0",
|
|
67
|
-
"jest": "^30.
|
|
68
|
-
"prettier": "^3.8.
|
|
69
|
-
"react": "^19.2.
|
|
70
|
-
"react-dom": "^19.2.
|
|
71
|
-
"type-fest": "^5.
|
|
72
|
-
"typescript": "^
|
|
67
|
+
"jest": "^30.4.2",
|
|
68
|
+
"prettier": "^3.8.3",
|
|
69
|
+
"react": "^19.2.6",
|
|
70
|
+
"react-dom": "^19.2.6",
|
|
71
|
+
"type-fest": "^5.6.0",
|
|
72
|
+
"typescript": "^6.0.3"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"eslint": ">= 9.28.0",
|