eslint-config-webpack 4.9.3 → 4.9.4

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.
@@ -2,6 +2,7 @@ import importPlugin from "eslint-plugin-import";
2
2
  import unicornPlugin from "eslint-plugin-unicorn";
3
3
  import globals from "globals";
4
4
 
5
+ /** @type {import("eslint").Linter.Config} */
5
6
  const recommendedBrowserOutdatedScriptConfig = {
6
7
  name: "browser/recommended-outdated-script",
7
8
  languageOptions: {
@@ -12,6 +13,7 @@ const recommendedBrowserOutdatedScriptConfig = {
12
13
  },
13
14
  };
14
15
 
16
+ /** @type {import("eslint").Linter.Config} */
15
17
  const recommendedBrowserOutdatedCommonjsConfig = {
16
18
  name: "browser/recommended-outdated-commonjs",
17
19
  languageOptions: {
@@ -22,6 +24,7 @@ const recommendedBrowserOutdatedCommonjsConfig = {
22
24
  },
23
25
  };
24
26
 
27
+ /** @type {import("eslint").Linter.Config} */
25
28
  const recommendedBrowserOutdatedModuleConfig = {
26
29
  name: "browser/recommended-outdated-module",
27
30
  languageOptions: {
@@ -32,6 +35,7 @@ const recommendedBrowserOutdatedModuleConfig = {
32
35
  },
33
36
  };
34
37
 
38
+ /** @type {import("eslint").Linter.Config} */
35
39
  const recommendedBrowserConfig = {
36
40
  name: "browser/recommended",
37
41
  languageOptions: {
package/configs/index.js CHANGED
@@ -9,17 +9,43 @@ import stylisticConfig from "./stylistic.js";
9
9
  import typescriptConfig from "./typescript.js";
10
10
  import webpackSpecial from "./webpack-special.js";
11
11
 
12
- const configs = {
13
- ...browserConfig,
14
- ...javascriptConfig,
15
- ...jestConfig,
16
- ...markdownConfig,
17
- ...nodeConfig,
18
- ...stylisticConfig,
19
- ...typescriptConfig,
20
- ...reactConfig,
21
- ...packageJSON,
22
- ...webpackSpecial,
23
- };
12
+ // TODO merge this file with config.js into one to avoid problems with types
13
+
14
+ /** @typedef {typeof browserConfig & typeof javascriptConfig & typeof jestConfig & typeof markdownConfig & typeof nodeConfig & typeof stylisticConfig & typeof typescriptConfig & typeof reactConfig & typeof packageJSON & typeof webpackSpecial} BasicConfigs */
15
+ /** @typedef {import("eslint").Linter.Config} Config */
16
+ /** @typedef {(Config | Config[])[]} NestedConfig */
17
+ /**
18
+ * @typedef {{
19
+ * recommended: NestedConfig,
20
+ * "node-recommended": NestedConfig,
21
+ * "recommended-module": NestedConfig,
22
+ * "node-recommended-module": NestedConfig,
23
+ * "recommended-commonjs": NestedConfig,
24
+ * "node-recommended-commonjs": NestedConfig,
25
+ * "recommended-dirty": NestedConfig,
26
+ * "node-recommended-dirty": NestedConfig,
27
+ * "browser-recommended": NestedConfig,
28
+ * "browser-outdated-recommended-script": NestedConfig,
29
+ * "browser-outdated-recommended-commonjs": NestedConfig,
30
+ * "browser-outdated-recommended-module": NestedConfig,
31
+ * "browser-outdated-recommended": NestedConfig,
32
+ * "universal-recommended": NestedConfig,
33
+ }} AddvancedConfigs */
34
+
35
+ /** @type {BasicConfigs & AddvancedConfigs} */
36
+ const configs =
37
+ /** @type {BasicConfigs & AddvancedConfigs} */
38
+ ({
39
+ ...browserConfig,
40
+ ...javascriptConfig,
41
+ ...jestConfig,
42
+ ...markdownConfig,
43
+ ...nodeConfig,
44
+ ...stylisticConfig,
45
+ ...typescriptConfig,
46
+ ...reactConfig,
47
+ ...packageJSON,
48
+ ...webpackSpecial,
49
+ });
24
50
 
25
51
  export default configs;
@@ -5,6 +5,7 @@ import globals from "globals";
5
5
  import { allExtensions, javascriptExtensions } from "./utils/extensions.js";
6
6
  import isTypescriptInstalled from "./utils/is-typescript-installed.js";
7
7
 
8
+ /** @type {import("eslint").Linter.Config["rules"]} */
8
9
  const possibleProblems = {
9
10
  "array-callback-return": [
10
11
  "error",
@@ -195,6 +196,7 @@ const possibleProblems = {
195
196
  // "valid-typeof": "error",
196
197
  };
197
198
 
199
+ /** @type {import("eslint").Linter.Config["rules"]} */
198
200
  const suggestions = {
199
201
  "accessor-pairs": "error",
200
202
 
@@ -336,7 +338,8 @@ const suggestions = {
336
338
  // No need
337
339
  // "max-statements": "off",
338
340
 
339
- "new-cap": "error",
341
+ // For `prop-types`
342
+ "new-cap": ["error", { capIsNewExceptionPattern: "^.+Type$" }],
340
343
 
341
344
  "no-alert": "error",
342
345
 
@@ -658,10 +661,12 @@ const suggestions = {
658
661
  yoda: "error",
659
662
  };
660
663
 
664
+ /** @type {import("eslint").Linter.Config["rules"]} */
661
665
  const layoutAndFormatting = {
662
666
  "unicode-bom": ["error", "never"],
663
667
  };
664
668
 
669
+ /** @type {import("eslint").Linter.Config["rules"]} */
665
670
  const unicornRules = {
666
671
  // No need
667
672
  // "unicorn/better-regex": "off",
@@ -730,6 +735,9 @@ const unicornRules = {
730
735
  // No need
731
736
  // "unicorn/import-style": "off",
732
737
 
738
+ // No need
739
+ // "unicorn/isolated-functions": "off",
740
+
733
741
  "unicorn/new-for-builtins": "error",
734
742
 
735
743
  "unicorn/no-abusive-eslint-disable": "error",
@@ -1045,6 +1053,7 @@ const unicornRules = {
1045
1053
  "unicorn/throw-new-error": "error",
1046
1054
  };
1047
1055
 
1056
+ /** @type {import("eslint").Linter.Config["rules"]} */
1048
1057
  const importRules = {
1049
1058
  ...importPlugin.flatConfigs.recommended.rules,
1050
1059
 
@@ -1196,52 +1205,62 @@ const importRules = {
1196
1205
  // "import/prefer-default-export": "off",
1197
1206
  };
1198
1207
 
1208
+ const needTypescriptSupport = isTypescriptInstalled();
1209
+ const extensions = needTypescriptSupport ? allExtensions : javascriptExtensions;
1210
+
1211
+ /** @type {import("eslint").Linter.Config} */
1212
+ const baseConfig = {
1213
+ ...javascriptConfig.configs.recommended,
1214
+ files: [`**/*.{${extensions.map((item) => item.slice(1)).join(",")}}`],
1215
+ ignores: ["**/*.d.ts"],
1216
+ settings: {
1217
+ "import/extensions": extensions,
1218
+ "import/ignore": [
1219
+ "eslint-plugin-.*",
1220
+ "\\.(coffee|scss|css|less|hbs|svg|md|jpg|jpeg|png|gif|webp|avif)$",
1221
+ ],
1222
+ "import/resolver": {
1223
+ node: {
1224
+ extensions: [...extensions],
1225
+ },
1226
+ },
1227
+ },
1228
+ plugins: {
1229
+ unicorn: unicornPlugin,
1230
+ import: importPlugin,
1231
+ },
1232
+ linterOptions: {
1233
+ reportUnusedDisableDirectives: true,
1234
+ reportUnusedInlineConfigs: "error",
1235
+ },
1236
+ rules: {
1237
+ ...javascriptConfig.configs.recommended.rules,
1238
+ ...possibleProblems,
1239
+ ...suggestions,
1240
+ ...layoutAndFormatting,
1241
+ ...unicornRules,
1242
+ ...importRules,
1243
+ },
1244
+ };
1245
+
1246
+ /** @typedef {2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026} Year */
1247
+
1199
1248
  /**
1200
- * @param {number} esVersion es version
1201
- * @returns {Record<string, string | number>} config
1249
+ * @param {Year | 5} esVersion es version
1250
+ * @returns {import("eslint").Linter.Config} config
1202
1251
  */
1203
1252
  function getConfig(esVersion) {
1204
- const extensions = isTypescriptInstalled()
1205
- ? allExtensions
1206
- : javascriptExtensions;
1207
1253
  const config = {
1208
- ...javascriptConfig.configs.recommended,
1254
+ ...baseConfig,
1209
1255
  name: `javascript/es${esVersion}`,
1210
- files: [`**/*.{${extensions.map((item) => item.slice(1)).join(",")}}`],
1211
- ignores: ["**/*.d.ts"],
1212
- settings: {
1213
- "import/extensions": extensions,
1214
- "import/ignore": [
1215
- "eslint-plugin-.*",
1216
- "\\.(coffee|scss|css|less|hbs|svg|md|jpg|jpeg|png|gif|webp|avif)$",
1217
- ],
1218
- "import/resolver": {
1219
- node: {
1220
- extensions: [...extensions],
1221
- },
1222
- },
1223
- },
1224
- plugins: {
1225
- unicorn: unicornPlugin,
1226
- import: importPlugin,
1227
- },
1228
1256
  languageOptions: {
1229
1257
  ecmaVersion: esVersion,
1230
1258
  globals: {
1231
1259
  ...globals[`es${esVersion}`],
1232
1260
  },
1233
1261
  },
1234
- linterOptions: {
1235
- reportUnusedDisableDirectives: true,
1236
- reportUnusedInlineConfigs: "error",
1237
- },
1238
1262
  rules: {
1239
- ...javascriptConfig.configs.recommended.rules,
1240
- ...possibleProblems,
1241
- ...suggestions,
1242
- ...layoutAndFormatting,
1243
- ...unicornRules,
1244
- ...importRules,
1263
+ ...baseConfig.rules,
1245
1264
  },
1246
1265
  };
1247
1266
 
@@ -1301,11 +1320,12 @@ function getConfig(esVersion) {
1301
1320
  return config;
1302
1321
  }
1303
1322
 
1323
+ /** @type {Record<"javascript/es5" | "javascript/recommended" | `javascript/es${Year}`, import("eslint").Linter.Config>} */
1304
1324
  const configs = {};
1305
- const esVersions = Array.from({ length: 11 }, (_x, i) => 15 + i);
1325
+ const esVersions = Array.from({ length: 12 }, (_x, i) => 15 + i);
1306
1326
 
1307
1327
  for (const [i, esVersion] of esVersions.entries()) {
1308
- const year = 2000 + esVersion;
1328
+ const year = /** @type {Year} */ (2000 + esVersion);
1309
1329
  const config = getConfig(year);
1310
1330
 
1311
1331
  configs[`javascript/es${year}`] = config;
package/configs/jest.js CHANGED
@@ -1,20 +1,33 @@
1
1
  import globals from "globals";
2
+ import getJsonFile from "./utils/get-json-file.js";
3
+
4
+ /** @type {import("type-fest").PackageJson | null} */
5
+ const packageJson = getJsonFile("package.json");
2
6
 
3
7
  /**
4
- * @returns {Promise<Record<string, string>>} config
8
+ * @returns {Promise<import("eslint").Linter.Config>} config
5
9
  */
6
10
  async function getJestRecommendedConfig() {
7
- let jestPlugin;
11
+ if (packageJson === null) {
12
+ return {
13
+ name: "jest/please-install-jest-to-enable-it",
14
+ };
15
+ }
16
+
17
+ const dependencies = packageJson.dependencies || {};
18
+ const devDependencies = packageJson.devDependencies || {};
8
19
 
9
- try {
10
- jestPlugin = (await import("eslint-plugin-jest")).default;
11
- // eslint-disable-next-line unicorn/prefer-optional-catch-binding
12
- } catch (_err) {
13
- // Nothing
20
+ if (
21
+ typeof dependencies.jest === "undefined" &&
22
+ typeof devDependencies.jest === "undefined"
23
+ ) {
24
+ return {
25
+ name: "jest/please-install-jest-to-enable-it",
26
+ };
14
27
  }
15
28
 
16
- const jsdocConfig =
17
- (jestPlugin && jestPlugin.configs["flat/recommended"]) || {};
29
+ const jestPlugin = (await import("eslint-plugin-jest")).default;
30
+ const jsdocConfig = jestPlugin.configs["flat/recommended"];
18
31
 
19
32
  return {
20
33
  ...jsdocConfig,
@@ -1,17 +1,10 @@
1
1
  import isTypescriptInstalled from "./utils/is-typescript-installed.js";
2
2
 
3
3
  /**
4
- * @returns {Promise<Record<string, string>>} config
4
+ * @returns {Promise<import("eslint").Linter.Config[]>} config
5
5
  */
6
6
  async function getMarkdownRecommendedConfig() {
7
- let markdownPlugin;
8
-
9
- try {
10
- markdownPlugin = (await import("@eslint/markdown")).default;
11
- // eslint-disable-next-line unicorn/prefer-optional-catch-binding
12
- } catch (_err) {
13
- // Nothing
14
- }
7
+ const markdownPlugin = (await import("@eslint/markdown")).default;
15
8
 
16
9
  return [
17
10
  {
package/configs/node.js CHANGED
@@ -2,6 +2,7 @@ import importPlugin from "eslint-plugin-import";
2
2
  import globals from "globals";
3
3
  import isTypescriptInstalled from "./utils/is-typescript-installed.js";
4
4
 
5
+ /** @type {import("eslint").Linter.Config["rules"]} */
5
6
  const commonRules = {
6
7
  // No need
7
8
  // "n/callback-return": "error",
@@ -101,12 +102,16 @@ const commonRules = {
101
102
 
102
103
  "n/prefer-global/console": ["error", "always"],
103
104
 
105
+ "n/prefer-global/crypto": ["error", "always"],
106
+
104
107
  "n/prefer-global/process": ["error", "always"],
105
108
 
106
109
  "n/prefer-global/text-decoder": ["error", "always"],
107
110
 
108
111
  "n/prefer-global/text-encoder": ["error", "always"],
109
112
 
113
+ "n/prefer-global/timers": ["error", "always"],
114
+
110
115
  "n/prefer-global/url": ["error", "always"],
111
116
 
112
117
  "n/prefer-global/url-search-params": ["error", "always"],
@@ -123,25 +128,14 @@ const commonRules = {
123
128
  // "n/process-exit-as-throw": "error",
124
129
  };
125
130
 
126
- let nodePlugin;
127
-
128
131
  const ignores = ["**/*.d.ts"];
129
132
 
130
133
  /**
131
- * @returns {Promise<Record<string, string>>} config
134
+ * @returns {Promise<import("eslint").Linter.Config>} config
132
135
  */
133
136
  async function getCommonJSConfig() {
134
- if (!nodePlugin) {
135
- try {
136
- nodePlugin = (await import("eslint-plugin-n")).default;
137
- // eslint-disable-next-line unicorn/prefer-optional-catch-binding
138
- } catch (_err) {
139
- // Nothing
140
- }
141
- }
142
-
143
- const nodeConfig =
144
- (nodePlugin && nodePlugin.configs["flat/recommended-script"]) || {};
137
+ const nodePlugin = (await import("eslint-plugin-n")).default;
138
+ const nodeConfig = nodePlugin.configs["flat/recommended-script"];
145
139
 
146
140
  return {
147
141
  ...nodeConfig,
@@ -183,22 +177,11 @@ async function getCommonJSConfig() {
183
177
  }
184
178
 
185
179
  /**
186
- * @returns {Promise<Record<string, string>>} config
180
+ * @returns {Promise<import("eslint").Linter.Config>} config
187
181
  */
188
182
  async function getModuleConfig() {
189
- let nodePlugin;
190
-
191
- if (!nodePlugin) {
192
- try {
193
- nodePlugin = (await import("eslint-plugin-n")).default;
194
- // eslint-disable-next-line unicorn/prefer-optional-catch-binding
195
- } catch (_err) {
196
- // Nothing
197
- }
198
- }
199
-
200
- const nodeConfig =
201
- (nodePlugin && nodePlugin.configs["flat/recommended-module"]) || {};
183
+ const nodePlugin = (await import("eslint-plugin-n")).default;
184
+ const nodeConfig = nodePlugin.configs["flat/recommended-module"];
202
185
 
203
186
  return {
204
187
  ...nodeConfig,
@@ -230,19 +213,10 @@ const commonjsConfig = await getCommonJSConfig();
230
213
  const moduleConfig = await getModuleConfig();
231
214
 
232
215
  /**
233
- * @returns {Promise<Record<string, string>>} config
216
+ * @returns {Promise<import("eslint").Linter.Config>} config
234
217
  */
235
218
  async function getDirtyConfig() {
236
- let nodePlugin;
237
-
238
- if (!nodePlugin) {
239
- try {
240
- nodePlugin = (await import("eslint-plugin-n")).default;
241
- // eslint-disable-next-line unicorn/prefer-optional-catch-binding
242
- } catch (_err) {
243
- // Nothing
244
- }
245
- }
219
+ const nodePlugin = (await import("eslint-plugin-n")).default;
246
220
 
247
221
  return {
248
222
  name: "node/dirty",
@@ -250,7 +224,12 @@ async function getDirtyConfig() {
250
224
  n: nodePlugin,
251
225
  import: importPlugin,
252
226
  },
253
- ignores: [...new Set([...commonjsConfig.ignores, ...moduleConfig.ignores])],
227
+ ignores: [
228
+ ...new Set([
229
+ ...(commonjsConfig.ignores || []),
230
+ ...(moduleConfig.ignores || []),
231
+ ]),
232
+ ],
254
233
  languageOptions: {
255
234
  sourceType: "module",
256
235
  parserOptions: {
@@ -1,8 +1,7 @@
1
1
  import { configs } from "../plugins/package-json/index.js";
2
2
 
3
- const recommendedBrowserConfig = {
4
- ...configs.recommended,
5
- };
3
+ /** @type {import("eslint").Linter.Config} */
4
+ const recommendedBrowserConfig = configs.recommended;
6
5
 
7
6
  export default {
8
7
  "package-json/recommended": recommendedBrowserConfig,
package/configs/react.js CHANGED
@@ -1,36 +1,42 @@
1
+ import getJsonFile from "./utils/get-json-file.js";
2
+
3
+ /** @type {import("type-fest").PackageJson | null} */
4
+ const packageJson = getJsonFile("package.json");
5
+
1
6
  /**
2
- * @returns {Promise<Record<string, string>>} config
7
+ * @returns {Promise<import("eslint").Linter.Config>} config
3
8
  */
4
9
  async function getReactRecommendedConfig() {
5
- let reactPlugin;
6
-
7
- try {
8
- reactPlugin = (await import("eslint-plugin-react")).default;
9
- // eslint-disable-next-line unicorn/prefer-optional-catch-binding
10
- } catch (_err) {
11
- // Nothing
10
+ if (packageJson === null) {
11
+ return {
12
+ name: "react/please-install-react-to-enable-it",
13
+ };
12
14
  }
13
15
 
14
- let reactHooksPlugin;
16
+ const dependencies = packageJson.dependencies || {};
17
+ const devDependencies = packageJson.devDependencies || {};
15
18
 
16
- try {
17
- reactHooksPlugin = (await import("eslint-plugin-react-hooks")).default;
18
- // eslint-disable-next-line unicorn/prefer-optional-catch-binding
19
- } catch (_err) {
20
- // Nothing
19
+ if (
20
+ typeof dependencies.react === "undefined" &&
21
+ typeof dependencies.preact === "undefined" &&
22
+ typeof devDependencies.react === "undefined" &&
23
+ typeof devDependencies.preact === "undefined"
24
+ ) {
25
+ return {
26
+ name: "react/please-install-react-to-enable-it",
27
+ };
21
28
  }
22
29
 
23
- const { recommended, "jsx-runtime": jsxRuntime } = (reactPlugin &&
24
- reactPlugin.configs &&
25
- reactPlugin.configs.flat) || { recommended: {}, "jsx-runtime": {} };
30
+ const reactPlugin = (await import("eslint-plugin-react")).default;
31
+ const { recommended, "jsx-runtime": jsxRuntime } = reactPlugin.configs.flat;
26
32
 
27
- const { recommended: recommendedHooks } = (reactHooksPlugin &&
28
- reactHooksPlugin.configs &&
29
- reactHooksPlugin.configs.flat) || { recommended: {} };
33
+ const reactHooksPlugin = (await import("eslint-plugin-react-hooks")).default;
34
+ const { recommended: recommendedHooks } = reactHooksPlugin.configs.flat;
30
35
 
31
36
  return {
32
37
  ...recommended,
33
38
  ...recommendedHooks,
39
+ name: "react/recommended",
34
40
  plugins: {
35
41
  ...recommended.plugins,
36
42
  ...recommendedHooks.plugins,
@@ -2,6 +2,7 @@ import stylisticPlugin from "@stylistic/eslint-plugin";
2
2
  import prettierPlugin from "eslint-plugin-prettier";
3
3
  import prettierConfig from "eslint-plugin-prettier/recommended";
4
4
 
5
+ /** @type {import("eslint").Linter.Config} */
5
6
  const recommendedConfig = {
6
7
  ...prettierConfig,
7
8
  name: "stylistic/recommended",