@zjutjh/eslint-config 2.0.0-beta.1 → 2.0.0-beta.3

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 CHANGED
@@ -97,9 +97,6 @@ export default zjutjh({
97
97
  overrides: {
98
98
  vue: {
99
99
  "vue/multi-word-component-names": ["off"]
100
- },
101
- stylistic: {
102
- "stylistic/quotes": ["error", "single"]
103
100
  }
104
101
  },
105
102
  ignores: [
@@ -117,11 +114,6 @@ export default zjutjh({
117
114
  export default zjutjh(
118
115
  // 第一个参数是 zjutjh 专用的配置
119
116
  {
120
- overrides: {
121
- stylistic: {
122
- "stylistic/quotes": ["error", "single"]
123
- }
124
- },
125
117
  ignores: [
126
118
  "**/build"
127
119
  ]
@@ -151,16 +143,15 @@ export default zjutjh(
151
143
 
152
144
  ## 代码格式化
153
145
 
154
- 很多人在意代码的格式化,这里单独拿出一章讲。
146
+ 内置 [oxfmt](https://oxc.rs/docs/guide/usage/formatter) 作为格式化工具,**默认开启**,覆盖 js(x)/ts(x)、
147
+ vue、css/scss/less、html、json/jsonc/json5 等文件。
155
148
 
156
- 内置两种格式化工具。`@stylistic/eslint-plugin` (lint 工具对格式的检查) 和传统的 formatter 工具
157
- ([oxfmt](https://oxc.rs/docs/guide/usage/formatter))。stylistic 默认开启,如果要使用 oxfmt,需要手动开启。
149
+ 如果不希望由 ESLint 进行格式化(例如团队另有格式化方案),可以关闭:
158
150
 
159
151
  ```ts
160
- // 启用 oxfmt
161
152
  export default zjutjh({
162
- oxfmt: true
163
- }),
153
+ oxfmt: false
154
+ })
164
155
  ```
165
156
 
166
157
  支持自定义 oxfmt 格式化选项,以及关闭对部分文件的格式化(默认对支持的文件全部开启)
@@ -179,8 +170,7 @@ export default zjutjh({
179
170
  })
180
171
  ```
181
172
 
182
- stylistic 只对 js(x) 和 ts(x) 进行格式化,而 oxfmt 还对其他文件,如 vue,css,html,json 等的格式化。
183
- 如果你要**在编辑器中**自动格式化这些文件,需要配置编辑器来允许 eslint 校验这些类型的文件。
173
+ 如果你要**在编辑器中**自动格式化非 js/ts 的文件,需要配置编辑器来允许 eslint 校验这些类型的文件。
184
174
 
185
175
  ```jsonc
186
176
  // @filename .vscode/settings.json
package/dist/index.d.mts CHANGED
@@ -6,7 +6,6 @@ import { FormatOptions } from "oxfmt";
6
6
  interface OverridesConfigs {
7
7
  vue?: Linter.RulesRecord;
8
8
  ts?: Linter.RulesRecord;
9
- stylistic?: Linter.RulesRecord;
10
9
  react?: Linter.RulesRecord;
11
10
  }
12
11
  interface OptionsConfig extends OptionsComponentExts {
@@ -34,7 +33,8 @@ interface OptionsOxfmt {
34
33
  /** js, ts, vue 文件 */es: boolean; /** css, less, scss 文件 */
35
34
  css: boolean;
36
35
  html: boolean; /** json, json5, jsonc 文件 */
37
- json: boolean;
36
+ json: boolean; /** yaml, yml 文件 */
37
+ yaml: boolean;
38
38
  };
39
39
  }
40
40
  //#endregion
package/dist/index.mjs CHANGED
@@ -2,12 +2,13 @@ import { isPackageExists } from "local-pkg";
2
2
  import { existsSync } from "node:fs";
3
3
  import { isAbsolute, resolve } from "node:path";
4
4
  import { includeIgnoreFile } from "@eslint/compat";
5
+ import { createNextImportResolver } from "eslint-import-resolver-next";
5
6
  import importXPlugin, { flatConfigs } from "eslint-plugin-import-x";
6
7
  import simpleImportSortPlugin from "eslint-plugin-simple-import-sort";
7
8
  import eslintJS from "@eslint/js";
8
9
  import globals from "globals";
9
10
  import uniconPlugin from "eslint-plugin-unicorn";
10
- import pluginStylistic from "@stylistic/eslint-plugin";
11
+ import pluginFormat from "eslint-plugin-format";
11
12
  //#region src/globs.ts
12
13
  const GLOB_VUE = "**/*.vue";
13
14
  const GLOB_JS = "**/*.?([cm])js";
@@ -21,6 +22,7 @@ const GLOB_HTML = "**/*.html";
21
22
  const GLOB_JSON = "**/*.json";
22
23
  const GLOB_JSON5 = "**/*.json5";
23
24
  const GLOB_JSONC = "**/*.jsonc";
25
+ const GLOB_YAML = "**/*.y?(a)ml";
24
26
  /**
25
27
  * @see https://github.com/antfu/eslint-config/blob/04ae86dd43e86d8b925555d85adf080494efeab3/src/globs.ts#L56
26
28
  */
@@ -81,7 +83,8 @@ function imports() {
81
83
  plugins: {
82
84
  "simple-import-sort": simpleImportSortPlugin,
83
85
  "import-x": importXPlugin
84
- }
86
+ },
87
+ settings: { "import-x/resolver-next": [createNextImportResolver()] }
85
88
  }, {
86
89
  name: "zjutjh/imports/rules",
87
90
  rules: {
@@ -119,7 +122,7 @@ function javascript() {
119
122
  name: "zjutjh/javascript/rules",
120
123
  rules: {
121
124
  ...eslintJS.configs.recommended.rules,
122
- "camelcase": "warn",
125
+ camelcase: "warn",
123
126
  "no-warning-comments": "warn",
124
127
  "no-console": ["warn", { allow: [
125
128
  "warn",
@@ -131,7 +134,7 @@ function javascript() {
131
134
  "prefer-const": "warn",
132
135
  "arrow-body-style": "error",
133
136
  "no-nested-ternary": "error",
134
- "curly": "error",
137
+ curly: "error",
135
138
  "no-else-return": "error",
136
139
  "no-implicit-coercion": "error",
137
140
  "no-useless-concat": "error",
@@ -156,31 +159,10 @@ function misc() {
156
159
  plugins: { unicorn: uniconPlugin }
157
160
  }, {
158
161
  name: "zjutjh/misc/rules",
159
- rules: { "unicorn/filename-case": ["error", { "case": "kebabCase" }] }
162
+ rules: { "unicorn/filename-case": ["error", { case: "kebabCase" }] }
160
163
  }];
161
164
  }
162
165
  //#endregion
163
- //#region src/utils.ts
164
- async function interopDefault(m) {
165
- const resolved = await m;
166
- return resolved.default || resolved;
167
- }
168
- async function ensurePackages(packages) {
169
- const nonExistingPackages = packages.filter((i) => i && !isPackageExists(i));
170
- if (nonExistingPackages.length === 0) return;
171
- if (await (await import("@clack/prompts")).confirm({ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?` })) {
172
- const { installPackage } = await import("@antfu/install-pkg");
173
- await installPackage(nonExistingPackages, { dev: true });
174
- }
175
- }
176
- function resolveSubOptions(options, key) {
177
- if (typeof options[key] === "boolean") return {};
178
- return options[key] || {};
179
- }
180
- function getOverrides(options, key) {
181
- return { ...options.overrides?.[key] };
182
- }
183
- //#endregion
184
166
  //#region src/configs/oxfmt.ts
185
167
  /**
186
168
  * @see https://oxc.rs/docs/guide/usage/formatter
@@ -203,10 +185,8 @@ const oxfmtOptions = {
203
185
  embeddedLanguageFormatting: "auto",
204
186
  singleAttributePerLine: false
205
187
  };
206
- async function oxfmt(options) {
207
- await ensurePackages(["eslint-plugin-format", "oxfmt"]);
208
- const pluginFormat = await interopDefault(import("eslint-plugin-format"));
209
- const { es: enableESFormat = true, html: enableHTMLFormat = true, css: enableCSSFormat = true, json: enableJSONFormat = true } = options?.lang ?? {};
188
+ function oxfmt(options) {
189
+ const { es: enableESFormat = true, html: enableHTMLFormat = true, css: enableCSSFormat = true, json: enableJSONFormat = true, yaml: enableYAMLFormat = true } = options?.lang ?? {};
210
190
  const mergedOptions = {
211
191
  ...oxfmtOptions,
212
192
  ...options?.oxfmtSelfOptions
@@ -252,10 +232,38 @@ async function oxfmt(options) {
252
232
  languageOptions: { parser: pluginFormat.parserPlain },
253
233
  plugins: { format: pluginFormat },
254
234
  rules: { "format/oxfmt": ["error", mergedOptions] }
235
+ } : {},
236
+ enableYAMLFormat ? {
237
+ name: "zjutjh/oxfmt/yaml",
238
+ files: [GLOB_YAML],
239
+ languageOptions: { parser: pluginFormat.parserPlain },
240
+ plugins: { format: pluginFormat },
241
+ rules: { "format/oxfmt": ["error", mergedOptions] }
255
242
  } : {}
256
243
  ];
257
244
  }
258
245
  //#endregion
246
+ //#region src/utils.ts
247
+ async function interopDefault(m) {
248
+ const resolved = await m;
249
+ return resolved.default || resolved;
250
+ }
251
+ async function ensurePackages(packages) {
252
+ const nonExistingPackages = packages.filter((i) => i && !isPackageExists(i));
253
+ if (nonExistingPackages.length === 0) return;
254
+ if (await (await import("@clack/prompts")).confirm({ message: `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?` })) {
255
+ const { installPackage } = await import("@antfu/install-pkg");
256
+ await installPackage(nonExistingPackages, { dev: true });
257
+ }
258
+ }
259
+ function resolveSubOptions(options, key) {
260
+ if (typeof options[key] === "boolean") return {};
261
+ return options[key] || {};
262
+ }
263
+ function getOverrides(options, key) {
264
+ return { ...options.overrides?.[key] };
265
+ }
266
+ //#endregion
259
267
  //#region src/configs/react.ts
260
268
  async function react(options) {
261
269
  await ensurePackages([
@@ -294,45 +302,6 @@ async function react(options) {
294
302
  }];
295
303
  }
296
304
  //#endregion
297
- //#region src/configs/stylistic.ts
298
- function stylistic(options) {
299
- return [{
300
- name: "zjutjh/stylistic/rules",
301
- plugins: { "@stylistic": pluginStylistic },
302
- rules: {
303
- "@stylistic/eol-last": ["error", "always"],
304
- "@stylistic/indent": ["error", 2],
305
- "@stylistic/keyword-spacing": "error",
306
- "@stylistic/key-spacing": "error",
307
- "@stylistic/no-trailing-spaces": "error",
308
- "@stylistic/linebreak-style": ["error", "unix"],
309
- "@stylistic/quotes": ["error", "double"],
310
- "@stylistic/function-call-spacing": "error",
311
- "@stylistic/semi": "error",
312
- "@stylistic/no-multiple-empty-lines": ["warn", { max: 1 }],
313
- "@stylistic/object-curly-spacing": ["error", "always"],
314
- "@stylistic/arrow-spacing": "error",
315
- "@stylistic/block-spacing": "error",
316
- "@stylistic/brace-style": "error",
317
- "@stylistic/comma-dangle": "error",
318
- "@stylistic/no-multi-spaces": "error",
319
- "@stylistic/comma-spacing": "error",
320
- "@stylistic/switch-colon-spacing": "error",
321
- "@stylistic/type-annotation-spacing": "error",
322
- "@stylistic/space-before-blocks": "error",
323
- "@stylistic/space-before-function-paren": ["error", {
324
- "anonymous": "never",
325
- "named": "never",
326
- "asyncArrow": "always"
327
- }],
328
- "@stylistic/space-in-parens": "error",
329
- "@stylistic/space-infix-ops": "error",
330
- "@stylistic/spaced-comment": "error",
331
- ...options.overrides
332
- }
333
- }];
334
- }
335
- //#endregion
336
305
  //#region src/configs/typescript.ts
337
306
  async function typescript(options) {
338
307
  const { componentExts = [], overrides, parserOptions } = options;
@@ -431,14 +400,16 @@ async function vue(options) {
431
400
  ...prev,
432
401
  ...curr
433
402
  }), {}),
403
+ "no-useless-assignment": "off",
434
404
  "vue/multi-word-component-names": ["warn", { ignores: ["index"] }],
435
405
  "vue/component-name-in-template-casing": [
436
406
  "error",
437
407
  "kebab-case",
438
- { "registeredComponentsOnly": true }
408
+ { registeredComponentsOnly: true }
439
409
  ],
440
- "vue/max-attributes-per-line": ["error", { "singleline": { "max": 3 } }],
441
410
  "vue/prefer-true-attribute-shorthand": ["warn", options?.taro ? "never" : "always"],
411
+ "vue/singleline-html-element-content-newline": "off",
412
+ "vue/html-self-closing": "off",
442
413
  ...options?.overrides
443
414
  }
444
415
  }];
@@ -446,12 +417,12 @@ async function vue(options) {
446
417
  //#endregion
447
418
  //#region src/factory.ts
448
419
  async function zjutjh(options = {}, ...userConfigs) {
449
- const { componentExts = [], vue: enableVue = isPackageExists("vue"), ts: enableTs = isPackageExists("typescript"), taro: enableTaro = isPackageExists("@tarojs/taro"), jsx: enableJSX = isPackageExists("react"), react: enableReact = isPackageExists("react"), ignores: userIgnores, gitignore: enableGitignore = false, oxfmt: enableOxfmt = false } = options;
420
+ const { componentExts = [], vue: enableVue = isPackageExists("vue"), ts: enableTs = isPackageExists("typescript"), taro: enableTaro = isPackageExists("@tarojs/taro"), jsx: enableJSX = isPackageExists("react"), react: enableReact = isPackageExists("react"), ignores: userIgnores, gitignore: enableGitignore = false, oxfmt: enableOxfmt = true } = options;
450
421
  const configs = [];
451
422
  configs.push(ignores({
452
423
  userIgnores,
453
424
  gitignore: enableGitignore
454
- }), javascript(), imports(), stylistic({ overrides: getOverrides(options, "stylistic") }), misc());
425
+ }), javascript(), imports(), misc());
455
426
  if (enableVue) componentExts.push("vue");
456
427
  const typescriptOptions = resolveSubOptions(options, "ts");
457
428
  if (enableTs) configs.push(await typescript({
@@ -467,7 +438,7 @@ async function zjutjh(options = {}, ...userConfigs) {
467
438
  if (enableJSX) configs.push(jsx());
468
439
  if (enableReact) configs.push(await react({ overrides: getOverrides(options, "react") }));
469
440
  const oxfmtOptions = resolveSubOptions(options, "oxfmt");
470
- if (enableOxfmt) configs.push(await oxfmt(oxfmtOptions));
441
+ if (enableOxfmt) configs.push(oxfmt(oxfmtOptions));
471
442
  return configs.flat(1).concat(userConfigs);
472
443
  }
473
444
  //#endregion
package/package.json CHANGED
@@ -1,42 +1,67 @@
1
1
  {
2
2
  "name": "@zjutjh/eslint-config",
3
- "type": "module",
4
- "version": "2.0.0-beta.1",
3
+ "version": "2.0.0-beta.3",
4
+ "description": "ESLint config used by zjutjh",
5
5
  "license": "ISC",
6
6
  "author": "zjutjh",
7
- "description": "ESLint config used by zjutjh",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/zjutjh/eslint-config.git"
10
+ },
8
11
  "files": [
9
12
  "dist"
10
13
  ],
14
+ "type": "module",
11
15
  "exports": {
12
16
  ".": {
13
- "import": "./dist/index.mjs",
14
- "types": "./dist/index.d.mts"
17
+ "types": "./dist/index.d.mts",
18
+ "import": "./dist/index.mjs"
15
19
  }
16
20
  },
17
- "engines": {
18
- "node": ">=24"
19
- },
20
- "repository": {
21
- "type": "git",
22
- "url": "https://github.com/zjutjh/eslint-config.git"
23
- },
24
21
  "publishConfig": {
25
22
  "registry": "https://registry.npmjs.org/"
26
23
  },
27
- "simple-git-hooks": {
28
- "pre-commit": "pnpm lint-staged"
24
+ "dependencies": {
25
+ "@antfu/install-pkg": "^1.1.0",
26
+ "@clack/prompts": "^1.2.0",
27
+ "@eslint/compat": "^2.0.5",
28
+ "@eslint/js": "^10.0.1",
29
+ "eslint-import-resolver-next": "^0.6.0",
30
+ "eslint-plugin-format": "^2.0.1",
31
+ "eslint-plugin-import-x": "^4.16.2",
32
+ "eslint-plugin-simple-import-sort": "^13.0.0",
33
+ "eslint-plugin-unicorn": "^64.0.0",
34
+ "globals": "^17.5.0",
35
+ "local-pkg": "^1.1.2",
36
+ "oxfmt": "^0.35.0"
37
+ },
38
+ "devDependencies": {
39
+ "@eslint-react/eslint-plugin": "^4.2.3",
40
+ "@eslint/config-inspector": "^2.0.0",
41
+ "@eslint/core": "^1.2.1",
42
+ "@types/node": "^25.6.0",
43
+ "@typescript-eslint/eslint-plugin": "^8.58.2",
44
+ "@typescript-eslint/parser": "^8.58.2",
45
+ "bumpp": "^11.0.1",
46
+ "cspell": "^10.0.0",
47
+ "eslint": "^10.2.1",
48
+ "eslint-plugin-react-hooks": "^7.1.1",
49
+ "eslint-plugin-react-refresh": "^0.5.2",
50
+ "eslint-plugin-vue": "^10.8.0",
51
+ "lint-staged": "^16.4.0",
52
+ "simple-git-hooks": "^2.13.1",
53
+ "tsdown": "^0.21.9",
54
+ "typescript": "^6.0.3",
55
+ "vue-eslint-parser": "^10.4.0"
29
56
  },
30
57
  "peerDependencies": {
31
58
  "@eslint-react/eslint-plugin": "^4.2.3",
32
59
  "@typescript-eslint/eslint-plugin": "^8.58.2",
33
60
  "@typescript-eslint/parser": "^8.58.2",
34
61
  "eslint": "^10.2.1",
35
- "eslint-plugin-format": "^2.0.1",
36
62
  "eslint-plugin-react-hooks": "^7.1.1",
37
63
  "eslint-plugin-react-refresh": "^0.5.2",
38
64
  "eslint-plugin-vue": "^10.8.0",
39
- "oxfmt": "^0.35.0",
40
65
  "vue-eslint-parser": "^10.4.0"
41
66
  },
42
67
  "peerDependenciesMeta": {
@@ -49,9 +74,6 @@
49
74
  "@typescript-eslint/parser": {
50
75
  "optional": true
51
76
  },
52
- "eslint-plugin-format": {
53
- "optional": true
54
- },
55
77
  "eslint-plugin-react-hooks": {
56
78
  "optional": true
57
79
  },
@@ -61,45 +83,15 @@
61
83
  "eslint-plugin-vue": {
62
84
  "optional": true
63
85
  },
64
- "oxfmt": {
65
- "optional": true
66
- },
67
86
  "vue-eslint-parser": {
68
87
  "optional": true
69
88
  }
70
89
  },
71
- "dependencies": {
72
- "@antfu/install-pkg": "^1.1.0",
73
- "@clack/prompts": "^1.2.0",
74
- "@eslint/compat": "^2.0.5",
75
- "@eslint/js": "^10.0.1",
76
- "@stylistic/eslint-plugin": "^5.10.0",
77
- "eslint-plugin-import-x": "^4.16.2",
78
- "eslint-plugin-simple-import-sort": "^13.0.0",
79
- "eslint-plugin-unicorn": "^64.0.0",
80
- "globals": "^17.5.0",
81
- "local-pkg": "^1.1.2"
90
+ "simple-git-hooks": {
91
+ "pre-commit": "pnpm lint-staged"
82
92
  },
83
- "devDependencies": {
84
- "@eslint-react/eslint-plugin": "^4.2.3",
85
- "@eslint/config-inspector": "^2.0.0",
86
- "@eslint/core": "^1.2.1",
87
- "@types/node": "^25.6.0",
88
- "@typescript-eslint/eslint-plugin": "^8.58.2",
89
- "@typescript-eslint/parser": "^8.58.2",
90
- "bumpp": "^11.0.1",
91
- "cspell": "^10.0.0",
92
- "eslint": "^10.2.1",
93
- "eslint-plugin-format": "^2.0.1",
94
- "eslint-plugin-react-hooks": "^7.1.1",
95
- "eslint-plugin-react-refresh": "^0.5.2",
96
- "eslint-plugin-vue": "^10.8.0",
97
- "lint-staged": "^16.4.0",
98
- "oxfmt": "^0.35.0",
99
- "simple-git-hooks": "^2.13.1",
100
- "tsdown": "^0.21.9",
101
- "typescript": "^6.0.3",
102
- "vue-eslint-parser": "^10.4.0"
93
+ "engines": {
94
+ "node": ">=24"
103
95
  },
104
96
  "scripts": {
105
97
  "build": "tsdown",