@huangjunsen/eslint-config 1.0.3 → 1.0.5

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.
@@ -0,0 +1,86 @@
1
+ /**
2
+ * 验证 Flat Config 预设
3
+ *
4
+ * 重点覆盖 Vue3 + TypeScript 场景:
5
+ * - 泛型箭头函数(<T,>)能被正常解析
6
+ * - 不会退回 espree 解析器
7
+ * - 噪音型风格规则保持关闭
8
+ */
9
+
10
+ const assert = require('assert');
11
+ const path = require('path');
12
+ const fs = require('fs-extra');
13
+ const { FlatESLint } = require('eslint/use-at-your-own-risk');
14
+
15
+ const cwd = path.resolve(__dirname, '..');
16
+ const fixtures = path.resolve(__dirname, './fixtures');
17
+ const tmpDir = path.resolve(__dirname, './.tmp-flat');
18
+
19
+ const VUE_FIXTURE = path.join(tmpDir, 'Generic.vue');
20
+ const TS_FIXTURE = path.join(tmpDir, 'generic.ts');
21
+
22
+ const VUE_SOURCE = `<template>
23
+ <div>{{ label }}</div>
24
+ </template>
25
+
26
+ <script lang="ts" setup>
27
+ const buildList = <T,>(list: T[] | undefined, getter: (item: T) => string) => {
28
+ return (list || []).map((item) => ({ name: getter(item) }));
29
+ };
30
+
31
+ const label = buildList([1, 2], (item) => String(item)).length;
32
+ </script>
33
+ `;
34
+
35
+ const TS_SOURCE = `export const toName = <T,>(item: T, getter: (value: T) => string): string => {
36
+ return getter(item);
37
+ };
38
+ `;
39
+
40
+ describe('Validate Flat configs', () => {
41
+ before(() => {
42
+ fs.outputFileSync(VUE_FIXTURE, VUE_SOURCE, 'utf8');
43
+ fs.outputFileSync(TS_FIXTURE, TS_SOURCE, 'utf8');
44
+ });
45
+
46
+ after(() => {
47
+ fs.removeSync(tmpDir);
48
+ });
49
+
50
+ it('flat/vue 能解析 TS 泛型与 Vue SFC', async () => {
51
+ const overrideConfig = [...require('../flat/vue.js'), ...require('../flat/typescript.js')];
52
+ const cli = new FlatESLint({ cwd, overrideConfigFile: true, overrideConfig });
53
+
54
+ const results = await cli.lintFiles([VUE_FIXTURE, TS_FIXTURE]);
55
+ assert.strictEqual(results.length, 2);
56
+
57
+ for (const result of results) {
58
+ const fatal = result.messages.filter((message) => message.fatal);
59
+ assert.strictEqual(
60
+ fatal.length,
61
+ 0,
62
+ `${path.basename(result.filePath)} 出现解析错误:${fatal.map((m) => m.message).join('; ')}`,
63
+ );
64
+ }
65
+ });
66
+
67
+ it('flat/vue 关闭了无法自动修复的格式类规则', () => {
68
+ const configs = require('../flat/vue.js');
69
+ const rules = Object.assign({}, ...configs.filter((config) => config.rules).map((c) => c.rules));
70
+
71
+ // 这些规则属于 eslint-plugin-vue 的 strongly-recommended / recommended 档位,
72
+ // 会产生大量无法被 Prettier 修复的告警,因此显式关闭
73
+ for (const rule of [
74
+ 'vue/attributes-order',
75
+ 'vue/attribute-hyphenation',
76
+ 'vue/require-default-prop',
77
+ 'vue/multi-word-component-names',
78
+ ]) {
79
+ assert.strictEqual(rules[rule], 'off', `${rule} 应保持关闭`);
80
+ }
81
+
82
+ // 正确性与安全性规则应保留
83
+ assert.strictEqual(rules['vue/no-v-html'], 'warn');
84
+ assert.strictEqual(rules['vue/no-mutating-props'], 'error');
85
+ });
86
+ });
package/flat/react.js CHANGED
@@ -4,6 +4,26 @@ const jsxA11y = require('eslint-plugin-jsx-a11y');
4
4
  const tsParser = require('@typescript-eslint/parser');
5
5
  const { prettierOverrides } = require('./shared');
6
6
 
7
+ /**
8
+ * React Hooks 经典规则
9
+ *
10
+ * eslint-plugin-react-hooks v7 的 `recommended` 预设新增了 14 条 React Compiler
11
+ * 相关规则(purity / immutability / refs / set-state-in-effect …),且大多为 error 级别。
12
+ * 这些规则用于配合 React Compiler 使用,在既有项目上会产生大量改动量极大的告警,
13
+ * 因此此处仅保留长期稳定、业界公认的两条经典规则;
14
+ * 需要启用编译器规则的项目可自行 extend:
15
+ *
16
+ * import reactHooks from 'eslint-plugin-react-hooks';
17
+ * export default [
18
+ * ...vueConfig,
19
+ * { plugins: { 'react-hooks': reactHooks }, rules: reactHooks.configs.recommended.rules },
20
+ * ];
21
+ */
22
+ const reactHooksRules = {
23
+ 'react-hooks/rules-of-hooks': 'error',
24
+ 'react-hooks/exhaustive-deps': 'warn',
25
+ };
26
+
7
27
  /**
8
28
  * React Flat Config 配置
9
29
  */
@@ -27,7 +47,7 @@ module.exports = [
27
47
  },
28
48
  rules: {
29
49
  ...react.configs.recommended.rules,
30
- ...reactHooks.configs.recommended.rules,
50
+ ...reactHooksRules,
31
51
  ...jsxA11y.configs.recommended.rules,
32
52
  },
33
53
  },
package/flat/vue.js CHANGED
@@ -6,12 +6,16 @@ const { toArray, prettierOverrides } = require('./shared');
6
6
  /**
7
7
  * Vue Flat Config 配置
8
8
  *
9
- * - 使用 eslint-plugin-vue 官方的 flat/recommended 规则集
10
- * - <script> lang 自动选择子解析器,因此 JS / TS 项目均可直接使用
9
+ * 规则档位选择 essential(而非 recommended):
10
+ * eslint-plugin-vue strongly-recommended / recommended 混入了大量格式类规则
11
+ * (attributes-order、attribute-hyphenation 等),它们无法被 Prettier 修复,
12
+ * 只会在扫描报告中长期堆积;真正有价值的正确性 / 安全规则已在下文显式开启。
13
+ *
14
+ * <script> 按 lang 自动选择子解析器,JS / TS / TSX 项目均可直接使用。
11
15
  */
12
16
  module.exports = [
13
17
  ...require('./index'),
14
- ...toArray(vue.configs['flat/recommended']),
18
+ ...toArray(vue.configs['flat/essential']),
15
19
  {
16
20
  name: 'fe-spec/vue/parser',
17
21
  files: ['**/*.vue'],
@@ -35,5 +39,27 @@ module.exports = [
35
39
  },
36
40
  },
37
41
  },
42
+ {
43
+ name: 'fe-spec/vue/rules',
44
+ files: ['**/*.vue'],
45
+ rules: {
46
+ // 【保留】v-html 存在 XSS 风险,需显式确认
47
+ 'vue/no-v-html': 'warn',
48
+ // 【保留】emits 显式声明,影响类型推导与可维护性
49
+ 'vue/require-explicit-emits': 'warn',
50
+
51
+ // 【关闭】组件名常由路由 / 目录结构决定,index、App 类入口组件
52
+ // 必然为单词,强制多词会产生大量误报
53
+ 'vue/multi-word-component-names': 'off',
54
+ // 【关闭】Vue2 时代规则:要求每个 prop 都有默认值。
55
+ // Vue3 使用 withDefaults(defineProps<T>()),可选 prop 由类型 `?` 表达
56
+ 'vue/require-default-prop': 'off',
57
+ // 【关闭】属性命名风格(kebab-case)属团队约定,非正确性问题
58
+ 'vue/attribute-hyphenation': 'off',
59
+ // 【关闭】属性排序属格式问题,Prettier 不处理,
60
+ // 开启会产生大量无法自动修复的告警
61
+ 'vue/attributes-order': 'off',
62
+ },
63
+ },
38
64
  ...prettierOverrides(),
39
65
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@huangjunsen/eslint-config",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "main": "index.js",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -26,6 +26,15 @@
26
26
  "node",
27
27
  "lint"
28
28
  ],
29
+ "peerDependencies": {
30
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
31
+ "typescript": ">=4.8.4 <6.1.0"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "typescript": {
35
+ "optional": true
36
+ }
37
+ },
29
38
  "author": "Huangjunsen <951434130@qq.com>",
30
39
  "homepage": "https://github.com/Huang-junsen/js-encode-fe-spec#readme",
31
40
  "license": "ISC",
@@ -42,24 +51,23 @@
42
51
  "@babel/preset-react": "^7.24.1",
43
52
  "@typescript-eslint/eslint-plugin": "^8.70.0",
44
53
  "@typescript-eslint/parser": "^8.70.0",
45
- "eslint-config-egg": "^13.1.0",
54
+ "eslint-config-egg": "^14.1.0",
46
55
  "eslint-config-prettier": "^10.1.8",
47
- "eslint-import-resolver-typescript": "^3.6.1",
56
+ "eslint-import-resolver-typescript": "^4.4.5",
48
57
  "eslint-plugin-import": "^2.29.1",
49
58
  "eslint-plugin-jsx-a11y": "^6.8.0",
50
- "eslint-plugin-jsx-plus": "^0.1.0",
51
59
  "eslint-plugin-react": "^7.34.1",
52
- "eslint-plugin-react-hooks": "^4.6.0",
60
+ "eslint-plugin-react-hooks": "^7.1.1",
53
61
  "eslint-plugin-vue": "^10.11.0",
54
- "globals": "^15.0.0",
62
+ "globals": "^17.12.0",
55
63
  "lodash": "^4.17.21",
56
64
  "typescript-eslint": "^8.70.0",
57
65
  "vue-eslint-parser": "^10.4.1"
58
66
  },
59
67
  "devDependencies": {
60
- "eslint": "^8.7.0",
68
+ "eslint": "^8.57.0",
61
69
  "mocha": "^10.4.0",
62
- "typescript": "5.0.4"
70
+ "typescript": "^5.0.4"
63
71
  },
64
72
  "scripts": {
65
73
  "lint": "eslint ./",
package/rules/react.js CHANGED
@@ -91,9 +91,6 @@ module.exports = {
91
91
  },
92
92
  ],
93
93
 
94
- // 本条废弃,用新规则代替 react/jsx-sort-props
95
- 'react/jsx-sort-prop-types': 'off',
96
-
97
94
  // 属性按首字母排序
98
95
  'react/jsx-sort-props': [
99
96
  'off',