eslint-config-webpack 4.9.5 → 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.
@@ -1241,7 +1241,7 @@ const baseConfig = {
1241
1241
  import: importPlugin,
1242
1242
  },
1243
1243
  linterOptions: {
1244
- reportUnusedDisableDirectives: true,
1244
+ reportUnusedDisableDirectives: "error",
1245
1245
  reportUnusedInlineConfigs: "error",
1246
1246
  },
1247
1247
  rules: {
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
- // From recommended
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
- // "n/no-unsupported-features/node-builtins": "error",
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 && packageJson.engines.node) {
19
- const minVersion = semver.minVersion(packageJson.engines.node);
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
- return configs["javascript/recommended"];
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.5",
3
+ "version": "4.9.6",
4
4
  "description": "Provides Webpack's eslint rules as an extensible shared config",
5
5
  "keywords": [
6
6
  "eslint",
@@ -45,31 +45,31 @@
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.1",
48
+ "eslint-plugin-jest": "^29.15.2",
49
49
  "eslint-plugin-jsdoc": "^62.9.0",
50
- "eslint-plugin-n": "^17.24.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.0.1",
53
+ "eslint-plugin-react-hooks": "^7.1.1",
54
54
  "eslint-plugin-unicorn": "^64.0.0",
55
- "globals": "^17.4.0",
55
+ "globals": "^17.6.0",
56
56
  "jsonc-eslint-parser": "^3.1.0",
57
- "semver": "^7.7.4",
57
+ "semver": "^7.8.0",
58
58
  "sort-package-json": "^3.6.0",
59
- "typescript-eslint": "^8.58.0"
59
+ "typescript-eslint": "^8.59.3"
60
60
  },
61
61
  "devDependencies": {
62
- "@changesets/cli": "^2.30.0",
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.3.0",
68
- "prettier": "^3.8.1",
69
- "react": "^19.2.3",
70
- "react-dom": "^19.2.3",
71
- "type-fest": "^5.5.0",
72
- "typescript": "^6.0.2"
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",