my-code-style 1.0.0 → 1.2.0
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/bin/{init.cjs → init} +50 -16
- package/package.json +40 -34
- package/src/commitlint/scopes.cjs +66 -7
- package/src/eslint/base.cjs +31 -8
- package/src/eslint/flat/_shared.mjs +28 -4
- package/src/eslint/flat/base.mjs +6 -1
- package/src/eslint/flat/vue3.mjs +12 -3
- package/src/eslint/vue3.cjs +12 -0
- package/src/gitattributes +8 -2
- package/src/prettier/index.cjs +12 -2
package/bin/{init.cjs → init}
RENAMED
|
@@ -54,7 +54,11 @@ function readTemplate(relativePath) {
|
|
|
54
54
|
function getProjectPkg() {
|
|
55
55
|
const pkgPath = path.resolve(PROJECT_ROOT, "package.json")
|
|
56
56
|
if (!fs.existsSync(pkgPath)) return null
|
|
57
|
-
|
|
57
|
+
try {
|
|
58
|
+
return JSON.parse(fs.readFileSync(pkgPath, "utf8"))
|
|
59
|
+
} catch {
|
|
60
|
+
return null
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
function getDependencyVersion(pkg, depName) {
|
|
@@ -98,8 +102,11 @@ function detectCssPreprocessor() {
|
|
|
98
102
|
// Fallback: check for existing stylelint config
|
|
99
103
|
if (fileExists(".stylelintrc.cjs") || fileExists(".stylelintrc.js")) {
|
|
100
104
|
try {
|
|
105
|
+
const stylelintFile = fileExists(".stylelintrc.cjs")
|
|
106
|
+
? ".stylelintrc.cjs"
|
|
107
|
+
: ".stylelintrc.js"
|
|
101
108
|
const content = fs.readFileSync(
|
|
102
|
-
path.resolve(PROJECT_ROOT,
|
|
109
|
+
path.resolve(PROJECT_ROOT, stylelintFile),
|
|
103
110
|
"utf8"
|
|
104
111
|
)
|
|
105
112
|
if (content.includes("postcss-less")) return "less"
|
|
@@ -141,12 +148,15 @@ function eslintFlatConfigContent(isUniApp) {
|
|
|
141
148
|
const importPath = isUniApp
|
|
142
149
|
? "my-code-style/eslint/flat/uniapp"
|
|
143
150
|
: "my-code-style/eslint/flat/vue3"
|
|
151
|
+
const varName = isUniApp ? "uniappConfig" : "vue3Config"
|
|
144
152
|
|
|
145
153
|
return `// ESLint Flat Config — powered by my-code-style
|
|
146
154
|
// https://www.npmjs.com/package/my-code-style
|
|
147
|
-
import
|
|
155
|
+
import ${varName} from "${importPath}"
|
|
148
156
|
|
|
149
|
-
export default
|
|
157
|
+
export default [
|
|
158
|
+
...${varName},
|
|
159
|
+
]
|
|
150
160
|
`
|
|
151
161
|
}
|
|
152
162
|
|
|
@@ -242,6 +252,13 @@ function getLintStagedConfig(cssPreprocessor) {
|
|
|
242
252
|
// --- Main ---
|
|
243
253
|
|
|
244
254
|
function main() {
|
|
255
|
+
// Handle --version / -v
|
|
256
|
+
if (process.argv.includes("--version") || process.argv.includes("-v")) {
|
|
257
|
+
const pkg = require("../package.json")
|
|
258
|
+
console.log(pkg.version)
|
|
259
|
+
return
|
|
260
|
+
}
|
|
261
|
+
|
|
245
262
|
const dryRun = process.argv.includes("--dry-run")
|
|
246
263
|
const label = dryRun ? "[DRY RUN] " : ""
|
|
247
264
|
|
|
@@ -273,8 +290,8 @@ function main() {
|
|
|
273
290
|
|
|
274
291
|
if (useFlatConfig) {
|
|
275
292
|
files.push({
|
|
276
|
-
path: "eslint.config.
|
|
277
|
-
exists: fileExists("eslint.config.
|
|
293
|
+
path: "eslint.config.mjs",
|
|
294
|
+
exists: fileExists("eslint.config.mjs") || fileExists("eslint.config.js") || fileExists("eslint.config.ts"),
|
|
278
295
|
content: eslintFlatConfigContent(uniApp),
|
|
279
296
|
})
|
|
280
297
|
} else {
|
|
@@ -385,7 +402,7 @@ function main() {
|
|
|
385
402
|
// package.json scripts + lint-staged
|
|
386
403
|
modifyPackageJson({
|
|
387
404
|
scripts: {
|
|
388
|
-
prepare: "husky
|
|
405
|
+
prepare: "husky",
|
|
389
406
|
release: "standard-version",
|
|
390
407
|
cz: "czg",
|
|
391
408
|
},
|
|
@@ -405,10 +422,14 @@ function main() {
|
|
|
405
422
|
if (useFlatConfig) {
|
|
406
423
|
console.log(" 2. Flat Config 需要的额外依赖:")
|
|
407
424
|
console.log(" pnpm add -D typescript-eslint globals eslint-plugin-import-x @eslint/js")
|
|
425
|
+
console.log(" 3. 初始化 husky:")
|
|
426
|
+
console.log(" pnpm prepare")
|
|
427
|
+
console.log(" 4. 使用 czg 提交 commit:")
|
|
428
|
+
} else {
|
|
429
|
+
console.log(" 2. 初始化 husky:")
|
|
430
|
+
console.log(" pnpm prepare")
|
|
431
|
+
console.log(" 3. 使用 czg 提交 commit:")
|
|
408
432
|
}
|
|
409
|
-
console.log(" 3. 初始化 husky:")
|
|
410
|
-
console.log(" pnpm prepare")
|
|
411
|
-
console.log(" 4. 使用 czg 提交 commit:")
|
|
412
433
|
console.log(" pnpm cz")
|
|
413
434
|
console.log("")
|
|
414
435
|
}
|
|
@@ -437,6 +458,7 @@ function checkPeerDeps({ useFlatConfig = false, cssPreprocessor = "scss" } = {})
|
|
|
437
458
|
const baseDeps = [
|
|
438
459
|
"eslint",
|
|
439
460
|
"prettier",
|
|
461
|
+
"eslint-plugin-vue",
|
|
440
462
|
"@commitlint/cli",
|
|
441
463
|
"husky",
|
|
442
464
|
"lint-staged",
|
|
@@ -445,17 +467,21 @@ function checkPeerDeps({ useFlatConfig = false, cssPreprocessor = "scss" } = {})
|
|
|
445
467
|
]
|
|
446
468
|
|
|
447
469
|
const flatDeps = useFlatConfig
|
|
448
|
-
? ["typescript-eslint", "globals", "eslint-plugin-import-x", "@eslint/js"]
|
|
449
|
-
: []
|
|
470
|
+
? ["typescript-eslint", "vue-eslint-parser", "globals", "eslint-plugin-import-x", "@eslint/js", "eslint-plugin-prettier", "eslint-config-prettier"]
|
|
471
|
+
: ["@typescript-eslint/parser", "@typescript-eslint/eslint-plugin", "eslint-plugin-prettier", "eslint-config-prettier"]
|
|
450
472
|
|
|
451
473
|
const cssDeps = cssPreprocessor === "scss"
|
|
452
|
-
? ["stylelint", "postcss-scss"]
|
|
474
|
+
? ["stylelint", "postcss-scss", "postcss-html"]
|
|
453
475
|
: cssPreprocessor === "less"
|
|
454
|
-
? ["stylelint", "postcss-less"]
|
|
476
|
+
? ["stylelint", "postcss-less", "postcss-html"]
|
|
455
477
|
: []
|
|
456
478
|
|
|
457
479
|
const allPeerDeps = [...baseDeps, ...flatDeps, ...cssDeps]
|
|
458
480
|
|
|
481
|
+
// Read peer dependency versions from my-code-style package.json
|
|
482
|
+
const packagePkg = JSON.parse(fs.readFileSync(path.resolve(PACKAGE_DIR, "package.json"), "utf8"))
|
|
483
|
+
const peerDeps = packagePkg.peerDependencies || {}
|
|
484
|
+
|
|
459
485
|
const pkgPath = path.resolve(PROJECT_ROOT, "package.json")
|
|
460
486
|
if (!fileExists("package.json")) return
|
|
461
487
|
|
|
@@ -468,8 +494,16 @@ function checkPeerDeps({ useFlatConfig = false, cssPreprocessor = "scss" } = {})
|
|
|
468
494
|
const missing = allPeerDeps.filter((dep) => !allDeps[dep])
|
|
469
495
|
if (missing.length > 0) {
|
|
470
496
|
console.log("")
|
|
471
|
-
warn("
|
|
472
|
-
|
|
497
|
+
warn(`以下依赖未安装:${missing.join(", ")}`)
|
|
498
|
+
console.log("")
|
|
499
|
+
warn("一键安装命令:")
|
|
500
|
+
console.log(` pnpm add -D my-code-style \\`)
|
|
501
|
+
missing.forEach((dep, i) => {
|
|
502
|
+
const version = peerDeps[dep] || ""
|
|
503
|
+
const depWithVersion = version ? `${dep}@${version}` : dep
|
|
504
|
+
const suffix = i < missing.length - 1 ? " \\" : ""
|
|
505
|
+
console.log(` ${depWithVersion}${suffix}`)
|
|
506
|
+
})
|
|
473
507
|
}
|
|
474
508
|
}
|
|
475
509
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-code-style",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Lint/Format/Git 配置工程化 npm 包(ESLint + Prettier + Stylelint + Commitlint + Husky + standard-version)",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "src/eslint/uniapp.cjs",
|
|
7
7
|
"bin": {
|
|
8
|
-
"my-code-style-init": "./bin/init
|
|
8
|
+
"my-code-style-init": "./bin/init"
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
|
11
11
|
".": "./src/eslint/uniapp.cjs",
|
|
@@ -29,43 +29,46 @@
|
|
|
29
29
|
"README.md"
|
|
30
30
|
],
|
|
31
31
|
"scripts": {
|
|
32
|
+
"link": "pnpm link --global",
|
|
33
|
+
"unlink": "pnpm unlink --global",
|
|
34
|
+
"pack": "npm pack",
|
|
32
35
|
"release": "standard-version"
|
|
33
36
|
},
|
|
34
37
|
"engines": {
|
|
35
38
|
"node": ">=18"
|
|
36
39
|
},
|
|
37
40
|
"peerDependencies": {
|
|
38
|
-
"@commitlint/cli": "
|
|
39
|
-
"@commitlint/config-conventional": "
|
|
40
|
-
"@eslint/eslintrc": "
|
|
41
|
-
"@eslint/js": "
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "
|
|
43
|
-
"@typescript-eslint/parser": "
|
|
44
|
-
"czg": "
|
|
45
|
-
"eslint": "
|
|
46
|
-
"eslint-config-prettier": "
|
|
47
|
-
"eslint-
|
|
48
|
-
"eslint-import
|
|
49
|
-
"eslint-plugin-import": "
|
|
50
|
-
"eslint-plugin-
|
|
51
|
-
"eslint-plugin-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"postcss-
|
|
57
|
-
"postcss-
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"stylelint": "
|
|
62
|
-
"stylelint-config-
|
|
63
|
-
"stylelint-config-
|
|
64
|
-
"stylelint-config-recommended": "
|
|
65
|
-
"stylelint-config-recommended-
|
|
66
|
-
"stylelint-
|
|
67
|
-
"
|
|
68
|
-
"
|
|
41
|
+
"@commitlint/cli": "^19.0.0",
|
|
42
|
+
"@commitlint/config-conventional": "^19.0.0",
|
|
43
|
+
"@eslint/eslintrc": "^3.0.0",
|
|
44
|
+
"@eslint/js": "^9.0.0",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
46
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
47
|
+
"czg": "^1.0.0",
|
|
48
|
+
"eslint": "^9.0.0",
|
|
49
|
+
"eslint-config-prettier": "^10.1.8",
|
|
50
|
+
"eslint-import-resolver-typescript": "^3.0.0",
|
|
51
|
+
"eslint-plugin-import": "^2.0.0",
|
|
52
|
+
"eslint-plugin-import-x": "^4.0.0",
|
|
53
|
+
"eslint-plugin-prettier": "^5.2.0",
|
|
54
|
+
"eslint-plugin-vue": "^10.0.0",
|
|
55
|
+
"globals": "^16.0.0",
|
|
56
|
+
"husky": "^9.0.0",
|
|
57
|
+
"lint-staged": "^16.0.0",
|
|
58
|
+
"postcss-html": "^1.0.0",
|
|
59
|
+
"postcss-less": "^6.0.0",
|
|
60
|
+
"postcss-scss": "^4.0.0",
|
|
61
|
+
"prettier": "^3.0.0",
|
|
62
|
+
"standard-version": "^9.0.0",
|
|
63
|
+
"stylelint": "^16.0.0",
|
|
64
|
+
"stylelint-config-html": "^1.0.0",
|
|
65
|
+
"stylelint-config-recess-order": "^5.0.0",
|
|
66
|
+
"stylelint-config-recommended": "^17.0.0",
|
|
67
|
+
"stylelint-config-recommended-scss": "^16.0.0",
|
|
68
|
+
"stylelint-config-recommended-vue": "^2.0.0",
|
|
69
|
+
"stylelint-prettier": "^5.0.0",
|
|
70
|
+
"typescript-eslint": "^8.0.0",
|
|
71
|
+
"vue-eslint-parser": "^9.0.0"
|
|
69
72
|
},
|
|
70
73
|
"peerDependenciesMeta": {
|
|
71
74
|
"@eslint/eslintrc": {
|
|
@@ -103,6 +106,9 @@
|
|
|
103
106
|
},
|
|
104
107
|
"typescript-eslint": {
|
|
105
108
|
"optional": true
|
|
109
|
+
},
|
|
110
|
+
"vue-eslint-parser": {
|
|
111
|
+
"optional": true
|
|
106
112
|
}
|
|
107
113
|
},
|
|
108
114
|
"devDependencies": {
|
|
@@ -118,4 +124,4 @@
|
|
|
118
124
|
"typescript"
|
|
119
125
|
],
|
|
120
126
|
"license": "MIT"
|
|
121
|
-
}
|
|
127
|
+
}
|
|
@@ -3,6 +3,63 @@ const fs = require("fs")
|
|
|
3
3
|
const path = require("path")
|
|
4
4
|
const { execSync } = require("child_process")
|
|
5
5
|
|
|
6
|
+
const PLURAL_MAP = {
|
|
7
|
+
components: "component",
|
|
8
|
+
views: "view",
|
|
9
|
+
pages: "page",
|
|
10
|
+
layouts: "layout",
|
|
11
|
+
hooks: "hook",
|
|
12
|
+
utils: "util",
|
|
13
|
+
stores: "store",
|
|
14
|
+
apis: "api",
|
|
15
|
+
services: "service",
|
|
16
|
+
plugins: "plugin",
|
|
17
|
+
directives: "directive",
|
|
18
|
+
filters: "filter",
|
|
19
|
+
constants: "constant",
|
|
20
|
+
helpers: "helper",
|
|
21
|
+
scripts: "script",
|
|
22
|
+
styles: "style",
|
|
23
|
+
types: "types",
|
|
24
|
+
settings: "setting",
|
|
25
|
+
assets: "asset",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function toSingular(name) {
|
|
29
|
+
if (!name) {
|
|
30
|
+
return name
|
|
31
|
+
}
|
|
32
|
+
if (PLURAL_MAP[name]) {
|
|
33
|
+
return PLURAL_MAP[name]
|
|
34
|
+
}
|
|
35
|
+
if (name.endsWith("ies") && name.length > 4) {
|
|
36
|
+
return name.slice(0, -3) + "y"
|
|
37
|
+
}
|
|
38
|
+
if (/(?:[sxz]|[ch|sh])es$/.test(name)) {
|
|
39
|
+
return name.slice(0, -2)
|
|
40
|
+
}
|
|
41
|
+
const nonPluralEndingInS = [
|
|
42
|
+
"status",
|
|
43
|
+
"canvas",
|
|
44
|
+
"bus",
|
|
45
|
+
"pass",
|
|
46
|
+
"process",
|
|
47
|
+
"css",
|
|
48
|
+
"less",
|
|
49
|
+
"scss",
|
|
50
|
+
"js",
|
|
51
|
+
"ts",
|
|
52
|
+
"types",
|
|
53
|
+
]
|
|
54
|
+
if (nonPluralEndingInS.includes(name.toLowerCase())) {
|
|
55
|
+
return name
|
|
56
|
+
}
|
|
57
|
+
if (name.endsWith("s") && !name.endsWith("ss") && name.length > 3) {
|
|
58
|
+
return name.slice(0, -1)
|
|
59
|
+
}
|
|
60
|
+
return name
|
|
61
|
+
}
|
|
62
|
+
|
|
6
63
|
/**
|
|
7
64
|
* Generate scopes by reading directory names
|
|
8
65
|
* @param {string|string[]} srcDirs - Source directory name(s) relative to cwd
|
|
@@ -14,11 +71,13 @@ function generateScopes(srcDirs = "src") {
|
|
|
14
71
|
|
|
15
72
|
for (const srcDir of dirs) {
|
|
16
73
|
const resolved = path.resolve(process.cwd(), srcDir)
|
|
17
|
-
if (!fs.existsSync(resolved))
|
|
74
|
+
if (!fs.existsSync(resolved)) {
|
|
75
|
+
continue
|
|
76
|
+
}
|
|
18
77
|
const scopes = fs
|
|
19
78
|
.readdirSync(resolved, { withFileTypes: true })
|
|
20
79
|
.filter((dirent) => dirent.isDirectory())
|
|
21
|
-
.map((dirent) => dirent.name
|
|
80
|
+
.map((dirent) => toSingular(dirent.name))
|
|
22
81
|
allScopes.push(...scopes)
|
|
23
82
|
}
|
|
24
83
|
|
|
@@ -33,11 +92,11 @@ function guessCurrentScope() {
|
|
|
33
92
|
try {
|
|
34
93
|
const output = execSync("git status --porcelain || true").toString().trim()
|
|
35
94
|
const line = output.split("\n").find((r) => r.includes("M src"))
|
|
36
|
-
if (!line)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
95
|
+
if (!line) {
|
|
96
|
+
return undefined
|
|
97
|
+
}
|
|
98
|
+
const rawName = line.replace(/\//g, "%%").match(/src%%((\w|-)*)/)?.[1]
|
|
99
|
+
return toSingular(rawName)
|
|
41
100
|
} catch {
|
|
42
101
|
return undefined
|
|
43
102
|
}
|
package/src/eslint/base.cjs
CHANGED
|
@@ -5,23 +5,40 @@ module.exports = {
|
|
|
5
5
|
es2021: true,
|
|
6
6
|
node: true,
|
|
7
7
|
},
|
|
8
|
+
parser: "@typescript-eslint/parser",
|
|
8
9
|
extends: [
|
|
9
10
|
"eslint:recommended",
|
|
10
11
|
"plugin:@typescript-eslint/recommended",
|
|
11
12
|
"plugin:import/recommended",
|
|
12
|
-
"standard",
|
|
13
13
|
"prettier",
|
|
14
14
|
"plugin:prettier/recommended",
|
|
15
15
|
],
|
|
16
16
|
parserOptions: {
|
|
17
17
|
ecmaVersion: "latest",
|
|
18
|
-
parser: "@typescript-eslint/parser",
|
|
19
18
|
sourceType: "module",
|
|
20
19
|
},
|
|
21
20
|
plugins: ["@typescript-eslint", "prettier", "import"],
|
|
22
21
|
rules: {
|
|
23
22
|
// Prettier 集成
|
|
24
|
-
"prettier/prettier": [
|
|
23
|
+
"prettier/prettier": [
|
|
24
|
+
"error",
|
|
25
|
+
{
|
|
26
|
+
singleQuote: false,
|
|
27
|
+
tabWidth: 4,
|
|
28
|
+
semi: false,
|
|
29
|
+
trailingComma: "all",
|
|
30
|
+
endOfLine: "lf",
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
// 格式化与风格
|
|
34
|
+
indent: ["error", 4],
|
|
35
|
+
semi: ["error", "never"],
|
|
36
|
+
quotes: ["error", "double", { avoidEscape: false, allowTemplateLiterals: true }],
|
|
37
|
+
curly: ["error", "all"],
|
|
38
|
+
"comma-dangle": ["error", "always-multiline"],
|
|
39
|
+
"object-curly-spacing": ["error", "always"],
|
|
40
|
+
"array-bracket-spacing": ["error", "never"],
|
|
41
|
+
|
|
25
42
|
// Import 相关
|
|
26
43
|
"import/no-unresolved": "off",
|
|
27
44
|
"import/extensions": [
|
|
@@ -29,12 +46,16 @@ module.exports = {
|
|
|
29
46
|
"ignorePackages",
|
|
30
47
|
{ js: "never", jsx: "never", ts: "never", tsx: "never" },
|
|
31
48
|
],
|
|
32
|
-
"import/prefer-default-export":
|
|
49
|
+
"import/prefer-default-export": "off",
|
|
33
50
|
"import/no-extraneous-dependencies": "off",
|
|
51
|
+
|
|
34
52
|
// TypeScript
|
|
35
53
|
"@typescript-eslint/no-redeclare": "error",
|
|
54
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
55
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
56
|
+
|
|
36
57
|
// 常用关闭
|
|
37
|
-
"no-console":
|
|
58
|
+
"no-console": "off",
|
|
38
59
|
"no-plusplus": "off",
|
|
39
60
|
"no-shadow": "off",
|
|
40
61
|
"no-underscore-dangle": "off",
|
|
@@ -42,14 +63,16 @@ module.exports = {
|
|
|
42
63
|
"no-undef": "off",
|
|
43
64
|
"no-unused-vars": "off",
|
|
44
65
|
"no-param-reassign": "off",
|
|
45
|
-
"@typescript-eslint/no-unused-vars": "off",
|
|
46
66
|
"no-redeclare": "off",
|
|
47
67
|
"prefer-promise-reject-errors": "off",
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
|
|
69
|
+
// Standard JS 风格规则已通过手动配置实现,不再依赖 eslint-config-standard
|
|
70
|
+
"style/quotes": "off",
|
|
71
|
+
"style/semi": "off",
|
|
50
72
|
},
|
|
51
73
|
settings: {
|
|
52
74
|
"import/parsers": { "@typescript-eslint/parser": [".ts", ".tsx"] },
|
|
53
75
|
"import/resolver": { typescript: {} },
|
|
54
76
|
},
|
|
55
77
|
}
|
|
78
|
+
|
|
@@ -4,13 +4,31 @@
|
|
|
4
4
|
* Prettier plugin rules — mirrors base.cjs prettier/prettier config
|
|
5
5
|
*/
|
|
6
6
|
export const prettierRules = {
|
|
7
|
-
"prettier/prettier": [
|
|
7
|
+
"prettier/prettier": [
|
|
8
|
+
"error",
|
|
9
|
+
{
|
|
10
|
+
singleQuote: false,
|
|
11
|
+
tabWidth: 4,
|
|
12
|
+
semi: false,
|
|
13
|
+
trailingComma: "all",
|
|
14
|
+
endOfLine: "lf",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
8
17
|
}
|
|
9
18
|
|
|
10
19
|
/**
|
|
11
20
|
* Common rules shared across all flat config levels — mirrors base.cjs rules
|
|
12
21
|
*/
|
|
13
22
|
export const commonRules = {
|
|
23
|
+
// 缩进与换行
|
|
24
|
+
indent: ["error", 4],
|
|
25
|
+
semi: ["error", "never"],
|
|
26
|
+
quotes: ["error", "double", { avoidEscape: false, allowTemplateLiterals: true }],
|
|
27
|
+
curly: ["error", "all"],
|
|
28
|
+
"comma-dangle": ["error", "always-multiline"],
|
|
29
|
+
"object-curly-spacing": ["error", "always"],
|
|
30
|
+
"array-bracket-spacing": ["error", "never"],
|
|
31
|
+
|
|
14
32
|
// Import rules (using import-x for flat config compatibility)
|
|
15
33
|
"import-x/no-unresolved": "off",
|
|
16
34
|
"import-x/extensions": [
|
|
@@ -20,8 +38,12 @@ export const commonRules = {
|
|
|
20
38
|
],
|
|
21
39
|
"import-x/prefer-default-export": "off",
|
|
22
40
|
"import-x/no-extraneous-dependencies": "off",
|
|
41
|
+
|
|
23
42
|
// TypeScript
|
|
24
43
|
"@typescript-eslint/no-redeclare": "error",
|
|
44
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
45
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
46
|
+
|
|
25
47
|
// Commonly disabled
|
|
26
48
|
"no-console": "off",
|
|
27
49
|
"no-plusplus": "off",
|
|
@@ -31,11 +53,12 @@ export const commonRules = {
|
|
|
31
53
|
"no-undef": "off",
|
|
32
54
|
"no-unused-vars": "off",
|
|
33
55
|
"no-param-reassign": "off",
|
|
34
|
-
"@typescript-eslint/no-unused-vars": "off",
|
|
35
56
|
"no-redeclare": "off",
|
|
36
57
|
"prefer-promise-reject-errors": "off",
|
|
37
|
-
|
|
38
|
-
|
|
58
|
+
|
|
59
|
+
// Standard JS uses @stylistic style/quotes — disable to avoid conflict
|
|
60
|
+
"style/quotes": "off",
|
|
61
|
+
"style/semi": "off",
|
|
39
62
|
}
|
|
40
63
|
|
|
41
64
|
/**
|
|
@@ -53,3 +76,4 @@ export const uniappGlobals = {
|
|
|
53
76
|
App: true,
|
|
54
77
|
NodeJS: true,
|
|
55
78
|
}
|
|
79
|
+
|
package/src/eslint/flat/base.mjs
CHANGED
|
@@ -43,7 +43,7 @@ export default [
|
|
|
43
43
|
// eslint-config-prettier MUST be last — disables conflicting ESLint rules
|
|
44
44
|
eslintConfigPrettier,
|
|
45
45
|
|
|
46
|
-
// Global language options
|
|
46
|
+
// Global language options for JS/TS
|
|
47
47
|
{
|
|
48
48
|
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
|
|
49
49
|
languageOptions: {
|
|
@@ -60,6 +60,11 @@ export default [
|
|
|
60
60
|
sourceType: "module",
|
|
61
61
|
},
|
|
62
62
|
},
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// Shared rules for all JS, TS and Vue files
|
|
66
|
+
{
|
|
67
|
+
files: ["**/*.{js,mjs,cjs,ts,mts,cts,vue}"],
|
|
63
68
|
rules: {
|
|
64
69
|
...prettierRules,
|
|
65
70
|
...commonRules,
|
package/src/eslint/flat/vue3.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Vue 3 ESLint Flat Config — extends base, adds Vue-specific rules
|
|
2
2
|
|
|
3
3
|
import pluginVue from "eslint-plugin-vue"
|
|
4
|
+
import tseslint from "typescript-eslint"
|
|
5
|
+
import parserVue from "vue-eslint-parser"
|
|
4
6
|
import baseConfig from "./base.mjs"
|
|
5
7
|
|
|
6
8
|
export default [
|
|
@@ -8,8 +10,6 @@ export default [
|
|
|
8
10
|
...baseConfig,
|
|
9
11
|
|
|
10
12
|
// Vue 3 essential rules
|
|
11
|
-
// Replaces: extends: ["plugin:vue/vue3-essential"]
|
|
12
|
-
// Must scope to .vue files only
|
|
13
13
|
...pluginVue.configs["flat/essential"].map((config) => ({
|
|
14
14
|
...config,
|
|
15
15
|
files: ["**/*.vue"],
|
|
@@ -19,15 +19,23 @@ export default [
|
|
|
19
19
|
{
|
|
20
20
|
files: ["**/*.vue"],
|
|
21
21
|
languageOptions: {
|
|
22
|
+
parser: parserVue,
|
|
22
23
|
parserOptions: {
|
|
23
|
-
parser:
|
|
24
|
+
parser: tseslint.parser,
|
|
24
25
|
sourceType: "module",
|
|
26
|
+
ecmaVersion: "latest",
|
|
27
|
+
extraFileExtensions: [".vue"],
|
|
25
28
|
},
|
|
26
29
|
},
|
|
27
30
|
rules: {
|
|
28
31
|
"vue/multi-word-component-names": "off",
|
|
29
32
|
"@typescript-eslint/no-explicit-any": "off",
|
|
30
33
|
"vue/no-mutating-props": ["error", { shallowOnly: true }],
|
|
34
|
+
"vue/html-indent": ["error", 4],
|
|
35
|
+
"vue/script-indent": "off",
|
|
36
|
+
"vue/html-self-closing": "off",
|
|
37
|
+
"vue/max-attributes-per-line": "off",
|
|
38
|
+
"vue/singleline-html-element-content-newline": "off",
|
|
31
39
|
},
|
|
32
40
|
},
|
|
33
41
|
|
|
@@ -44,3 +52,4 @@ export default [
|
|
|
44
52
|
},
|
|
45
53
|
},
|
|
46
54
|
]
|
|
55
|
+
|
package/src/eslint/vue3.cjs
CHANGED
|
@@ -3,7 +3,13 @@ const base = require("./base.cjs")
|
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
5
|
...base,
|
|
6
|
+
parser: "vue-eslint-parser",
|
|
6
7
|
extends: [...base.extends, "plugin:vue/vue3-essential"],
|
|
8
|
+
parserOptions: {
|
|
9
|
+
...base.parserOptions,
|
|
10
|
+
parser: "@typescript-eslint/parser",
|
|
11
|
+
extraFileExtensions: [".vue"],
|
|
12
|
+
},
|
|
7
13
|
plugins: [...base.plugins, "vue"],
|
|
8
14
|
overrides: [
|
|
9
15
|
{
|
|
@@ -19,5 +25,11 @@ module.exports = {
|
|
|
19
25
|
"vue/multi-word-component-names": "off",
|
|
20
26
|
"@typescript-eslint/no-explicit-any": "off",
|
|
21
27
|
"vue/no-mutating-props": ["error", { shallowOnly: true }],
|
|
28
|
+
"vue/html-indent": ["error", 4],
|
|
29
|
+
"vue/script-indent": "off",
|
|
30
|
+
"vue/html-self-closing": "off",
|
|
31
|
+
"vue/max-attributes-per-line": "off",
|
|
32
|
+
"vue/singleline-html-element-content-newline": "off",
|
|
22
33
|
},
|
|
23
34
|
}
|
|
35
|
+
|
package/src/gitattributes
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# Automatically normalize line endings (to LF) for all text-based files.
|
|
2
|
+
* text=auto eol=lf
|
|
3
|
+
|
|
4
|
+
# Windows scripts — must use CRLF
|
|
5
|
+
*.{cmd,[cC][mM][dD]} text eol=crlf
|
|
6
|
+
*.{bat,[bB][aA][tT]} text eol=crlf
|
|
7
|
+
*.{ps1,[pP][sS]1} text eol=crlf
|
|
2
8
|
|
|
3
9
|
# Binary files — do not apply EOL conversion
|
|
4
10
|
*.aar binary
|
|
@@ -16,4 +22,4 @@
|
|
|
16
22
|
*.woff binary
|
|
17
23
|
*.woff2 binary
|
|
18
24
|
*.apk binary
|
|
19
|
-
*.plist binary
|
|
25
|
+
*.plist binary
|
package/src/prettier/index.cjs
CHANGED
|
@@ -10,8 +10,17 @@ module.exports = {
|
|
|
10
10
|
htmlWhitespaceSensitivity: "ignore",
|
|
11
11
|
overrides: [
|
|
12
12
|
{
|
|
13
|
-
files: "*.json",
|
|
14
|
-
options: {
|
|
13
|
+
files: ["*.json", "*.json5"],
|
|
14
|
+
options: {
|
|
15
|
+
tabWidth: 2,
|
|
16
|
+
trailingComma: "none",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
files: ["*.yml", "*.yaml"],
|
|
21
|
+
options: {
|
|
22
|
+
tabWidth: 2,
|
|
23
|
+
},
|
|
15
24
|
},
|
|
16
25
|
{
|
|
17
26
|
files: "*.nvue",
|
|
@@ -19,3 +28,4 @@ module.exports = {
|
|
|
19
28
|
},
|
|
20
29
|
],
|
|
21
30
|
}
|
|
31
|
+
|