UNPKG

@qes-test/eslint-config

Version:

ESLint configuration for QES projects

1,164 lines (1,144 loc) 33.9 kB
import createCommand from 'eslint-plugin-command/config'; import * as pluginImport from 'eslint-plugin-import-x'; import js from '@eslint/js'; import pluginUnusedImports from 'eslint-plugin-unused-imports'; import globals from 'globals'; import typescriptEslint from '@typescript-eslint/eslint-plugin'; async function command() { return [ { ...createCommand() } ]; } async function interopDefault(m) { const resolved = await m; return resolved.default || resolved; } async function comments() { const [pluginComments] = await Promise.all([ // @ts-expect-error - no types interopDefault(import('eslint-plugin-eslint-comments')) ]); return [ { plugins: { "eslint-comments": pluginComments }, rules: { "eslint-comments/no-aggregating-enable": "error", "eslint-comments/no-duplicate-disable": "error", "eslint-comments/no-unlimited-disable": "error", "eslint-comments/no-unused-enable": "error" } } ]; } async function disableds() { return [ { files: ["**/__tests__/**/*.?([cm])[jt]s?(x)"], name: "disables/test", rules: { "@typescript-eslint/ban-ts-comment": "off", "no-console": "off" } }, { files: ["**/*.d.ts"], name: "disables/dts", rules: { "@typescript-eslint/triple-slash-reference": "off" } }, { files: ["**/*.js", "**/*.mjs", "**/*.cjs"], name: "disables/js", rules: { "@typescript-eslint/explicit-module-boundary-types": "off" } } ]; } async function ignores() { return [ { ignores: [ "**/node_modules", "**/dist", "**/dist-*", "**/*-dist", "**/.husky", "**/.nitro", "**/.output", "**/Dockerfile", "**/package-lock.json", "**/yarn.lock", "**/pnpm-lock.yaml", "**/bun.lockb", "**/output", "**/coverage", "**/temp", "**/.temp", "**/tmp", "**/.tmp", "**/.history", "**/.turbo", "**/.nuxt", "**/.next", "**/.vercel", "**/.changeset", "**/.idea", "**/.cache", "**/.output", "**/.vite-inspect", "**/CHANGELOG*.md", "**/*.min.*", "**/LICENSE*", "**/__snapshots__", "**/*.snap", "**/fixtures/**", "**/.vitepress/cache/**", "**/auto-import?(s).d.ts", "**/components.d.ts", "**/vite.config.mts.*", "**/*.sh", "**/*.ttf", "**/*.woff" ] } ]; } async function importPluginConfig() { return [ { plugins: { // @ts-expect-error - This is a dynamic import import: pluginImport }, rules: { "import/consistent-type-specifier-style": ["error", "prefer-top-level"], "import/first": "error", "import/newline-after-import": "error", "import/no-duplicates": "error", "import/no-mutable-exports": "error", "import/no-named-default": "error", "import/no-self-import": "error", "import/no-unresolved": "off", "import/no-webpack-loader-syntax": "error" } } ]; } async function javascript() { return [ { languageOptions: { ecmaVersion: "latest", globals: { ...globals.browser, ...globals.es2021, ...globals.node, document: "readonly", navigator: "readonly", window: "readonly" }, parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: "latest", sourceType: "module" }, sourceType: "module" }, linterOptions: { reportUnusedDisableDirectives: true }, plugins: { "unused-imports": pluginUnusedImports }, rules: { ...js.configs.recommended.rules, "accessor-pairs": [ "error", { enforceForClassMembers: true, setWithoutGet: true } ], "array-callback-return": "error", "block-scoped-var": "error", "constructor-super": "error", "default-case-last": "error", "dot-notation": ["error", { allowKeywords: true }], eqeqeq: ["error", "always"], "keyword-spacing": "off", "new-cap": [ "error", { capIsNew: false, newIsCap: true, properties: true } ], "no-alert": "off", "no-array-constructor": "error", "no-async-promise-executor": "error", "no-caller": "error", "no-case-declarations": "error", "no-class-assign": "error", "no-compare-neg-zero": "error", "no-cond-assign": ["error", "always"], "no-console": ["error", { allow: ["warn", "error"] }], "no-const-assign": "error", "no-control-regex": "error", "no-debugger": "error", "no-delete-var": "error", "no-dupe-args": "error", "no-dupe-class-members": "error", "no-dupe-keys": "error", "no-duplicate-case": "error", "no-empty": ["error", { allowEmptyCatch: true }], "no-empty-character-class": "error", "no-empty-function": "off", "no-empty-pattern": "error", "no-eval": "error", "no-ex-assign": "error", "no-extend-native": "error", "no-extra-bind": "error", "no-extra-boolean-cast": "error", "no-fallthrough": "error", "no-func-assign": "error", "no-global-assign": "error", "no-implied-eval": "error", "no-import-assign": "error", "no-invalid-regexp": "error", "no-irregular-whitespace": "error", "no-iterator": "error", "no-labels": ["error", { allowLoop: false, allowSwitch: false }], "no-lone-blocks": "error", "no-loss-of-precision": "error", "no-misleading-character-class": "error", "no-multi-str": "error", "no-new": "error", "no-new-func": "error", "no-new-object": "error", "no-new-symbol": "error", "no-new-wrappers": "error", "no-obj-calls": "error", "no-octal": "error", "no-octal-escape": "error", "no-proto": "error", "no-prototype-builtins": "error", "no-redeclare": ["error", { builtinGlobals: false }], "no-regex-spaces": "error", "no-restricted-globals": [ "error", { message: "Use `globalThis` instead.", name: "global" }, { message: "Use `globalThis` instead.", name: "self" } ], "no-restricted-properties": [ "error", { message: "Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.", property: "__proto__" }, { message: "Use `Object.defineProperty` instead.", property: "__defineGetter__" }, { message: "Use `Object.defineProperty` instead.", property: "__defineSetter__" }, { message: "Use `Object.getOwnPropertyDescriptor` instead.", property: "__lookupGetter__" }, { message: "Use `Object.getOwnPropertyDescriptor` instead.", property: "__lookupSetter__" } ], "no-restricted-syntax": [ "error", "DebuggerStatement", "LabeledStatement", "WithStatement", "TSEnumDeclaration[const=true]", "TSExportAssignment" ], "no-self-assign": ["error", { props: true }], "no-self-compare": "error", "no-sequences": "error", "no-shadow-restricted-names": "error", "no-sparse-arrays": "error", "no-template-curly-in-string": "error", "no-this-before-super": "error", "no-throw-literal": "error", "no-undef": "off", "no-undef-init": "error", "no-unexpected-multiline": "error", "no-unmodified-loop-condition": "error", "no-unneeded-ternary": ["error", { defaultAssignment: false }], "no-unreachable": "error", "no-unreachable-loop": "error", "no-unsafe-finally": "error", "no-unsafe-negation": "error", "no-unused-expressions": [ "error", { allowShortCircuit: true, allowTaggedTemplates: true, allowTernary: true } ], "no-unused-vars": "off", "no-use-before-define": [ "error", { classes: false, functions: false, variables: false } ], "no-useless-backreference": "error", "no-useless-call": "error", "no-useless-catch": "error", "no-useless-computed-key": "error", "no-useless-constructor": "error", "no-useless-rename": "error", "no-useless-return": "error", "no-var": "error", "no-with": "error", "object-shorthand": [ "error", "always", { avoidQuotes: true, ignoreConstructors: false } ], "one-var": ["error", { initialized: "never" }], "prefer-arrow-callback": [ "error", { allowNamedFunctions: false, allowUnboundThis: true } ], "prefer-const": [ "error", { destructuring: "all", ignoreReadBeforeAssign: true } ], "prefer-exponentiation-operator": "error", "prefer-promise-reject-errors": "error", "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }], "prefer-rest-params": "error", "prefer-template": "error", "space-before-function-paren": "off", "spaced-comment": "error", "symbol-description": "error", "unicode-bom": ["error", "never"], "unused-imports/no-unused-imports": "error", "unused-imports/no-unused-vars": [ "error", { vars: "all", varsIgnorePattern: "^_", args: "all", argsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" } ], "use-isnan": [ "error", { enforceForIndexOf: true, enforceForSwitchCase: true } ], "valid-typeof": ["error", { requireStringLiterals: true }], "vars-on-top": "error", yoda: ["error", "never"] } } ]; } async function jsdoc() { const [pluginJsdoc] = await Promise.all([ interopDefault(import('eslint-plugin-jsdoc')) ]); return [ { plugins: { jsdoc: pluginJsdoc }, rules: { "jsdoc/check-access": "warn", "jsdoc/check-param-names": "warn", "jsdoc/check-property-names": "warn", "jsdoc/check-types": "warn", "jsdoc/empty-tags": "warn", "jsdoc/implements-on-classes": "warn", "jsdoc/no-defaults": "warn", "jsdoc/no-multi-asterisks": "warn", "jsdoc/require-param-name": "warn", "jsdoc/require-property": "warn", "jsdoc/require-property-description": "warn", "jsdoc/require-property-name": "warn", "jsdoc/require-returns-check": "warn", "jsdoc/require-returns-description": "warn", "jsdoc/require-yields-check": "warn" } } ]; } async function jsonc() { const [pluginJsonc, parserJsonc] = await Promise.all([ interopDefault(import('eslint-plugin-jsonc')), interopDefault(import('jsonc-eslint-parser')) ]); return [ { files: ["**/*.json", "**/*.json5", "**/*.jsonc", "*.code-workspace"], languageOptions: { parser: parserJsonc }, plugins: { jsonc: pluginJsonc }, rules: { "jsonc/no-bigint-literals": "error", "jsonc/no-binary-expression": "error", "jsonc/no-binary-numeric-literals": "error", "jsonc/no-dupe-keys": "error", "jsonc/no-escape-sequence-in-identifier": "error", "jsonc/no-floating-decimal": "error", "jsonc/no-hexadecimal-numeric-literals": "error", "jsonc/no-infinity": "error", "jsonc/no-multi-str": "error", "jsonc/no-nan": "error", "jsonc/no-number-props": "error", "jsonc/no-numeric-separators": "error", "jsonc/no-octal": "error", "jsonc/no-octal-escape": "error", "jsonc/no-octal-numeric-literals": "error", "jsonc/no-parenthesized": "error", "jsonc/no-plus-sign": "error", "jsonc/no-regexp-literals": "error", "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-unicode-codepoint-escapes": "error", "jsonc/no-useless-escape": "error", "jsonc/space-unary-ops": "error", "jsonc/valid-json-number": "error", "jsonc/vue-custom-block/no-parsing-error": "error" } }, sortTsconfig(), sortPackageJson() ]; } function sortPackageJson() { return { files: ["**/package.json"], rules: { "jsonc/sort-array-values": [ "error", { order: { type: "asc" }, pathPattern: "^files$|^pnpm.neverBuiltDependencies$" } ], "jsonc/sort-keys": [ "error", { order: [ "name", "version", "description", "private", "keywords", "homepage", "bugs", "repository", "license", "author", "contributors", "categories", "funding", "type", "scripts", "files", "sideEffects", "bin", "main", "module", "unpkg", "jsdelivr", "types", "typesVersions", "imports", "exports", "publishConfig", "icon", "activationEvents", "contributes", "peerDependencies", "peerDependenciesMeta", "dependencies", "optionalDependencies", "devDependencies", "engines", "packageManager", "pnpm", "overrides", "resolutions", "husky", "simple-git-hooks", "lint-staged", "eslintConfig" ], pathPattern: "^$" }, { order: { type: "asc" }, pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$" }, { order: { type: "asc" }, pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$" }, { order: ["types", "import", "require", "default"], pathPattern: "^exports.*$" } ] } }; } function sortTsconfig() { return { files: [ "**/tsconfig.json", "**/tsconfig.*.json", "internal/tsconfig/*.json" ], rules: { "jsonc/sort-keys": [ "error", { order: [ "extends", "compilerOptions", "references", "files", "include", "exclude" ], pathPattern: "^$" }, { order: [ /* Projects */ "incremental", "composite", "tsBuildInfoFile", "disableSourceOfProjectReferenceRedirect", "disableSolutionSearching", "disableReferencedProjectLoad", /* Language and Environment */ "target", "jsx", "jsxFactory", "jsxFragmentFactory", "jsxImportSource", "lib", "moduleDetection", "noLib", "reactNamespace", "useDefineForClassFields", "emitDecoratorMetadata", "experimentalDecorators", /* Modules */ "baseUrl", "rootDir", "rootDirs", "customConditions", "module", "moduleResolution", "moduleSuffixes", "noResolve", "paths", "resolveJsonModule", "resolvePackageJsonExports", "resolvePackageJsonImports", "typeRoots", "types", "allowArbitraryExtensions", "allowImportingTsExtensions", "allowUmdGlobalAccess", /* JavaScript Support */ "allowJs", "checkJs", "maxNodeModuleJsDepth", /* Type Checking */ "strict", "strictBindCallApply", "strictFunctionTypes", "strictNullChecks", "strictPropertyInitialization", "allowUnreachableCode", "allowUnusedLabels", "alwaysStrict", "exactOptionalPropertyTypes", "noFallthroughCasesInSwitch", "noImplicitAny", "noImplicitOverride", "noImplicitReturns", "noImplicitThis", "noPropertyAccessFromIndexSignature", "noUncheckedIndexedAccess", "noUnusedLocals", "noUnusedParameters", "useUnknownInCatchVariables", /* Emit */ "declaration", "declarationDir", "declarationMap", "downlevelIteration", "emitBOM", "emitDeclarationOnly", "importHelpers", "importsNotUsedAsValues", "inlineSourceMap", "inlineSources", "mapRoot", "newLine", "noEmit", "noEmitHelpers", "noEmitOnError", "outDir", "outFile", "preserveConstEnums", "preserveValueImports", "removeComments", "sourceMap", "sourceRoot", "stripInternal", /* Interop Constraints */ "allowSyntheticDefaultImports", "esModuleInterop", "forceConsistentCasingInFileNames", "isolatedModules", "preserveSymlinks", "verbatimModuleSyntax", /* Completeness */ "skipDefaultLibCheck", "skipLibCheck" ], pathPattern: "^compilerOptions$" } ] } }; } async function node() { const pluginNode = await interopDefault(import('eslint-plugin-n')); return [ { plugins: { n: pluginNode }, rules: { "n/handle-callback-err": ["error", "^(err|error)$"], "n/no-deprecated-api": "error", "n/no-exports-assign": "error", "n/no-extraneous-import": [ "error", { allowModules: [ "unbuild", "@qes/vite-config", "vitest", "vite", "@vue/test-utils", "@qes/tailwind-config", "@playwright/test" ] } ], "n/no-new-require": "error", "n/no-path-concat": "error", // 'n/no-unpublished-import': 'off', "n/no-unsupported-features/es-syntax": [ "error", { ignores: [], version: ">=18.0.0" } ], "n/prefer-global/buffer": ["error", "never"], // 'n/no-missing-import': 'off', "n/prefer-global/process": ["error", "never"], "n/process-exit-as-throw": "error" } }, { files: [ "scripts/**/*.?([cm])[jt]s?(x)", "internal/**/*.?([cm])[jt]s?(x)" ], rules: { "n/prefer-global/process": "off" } } ]; } async function perfectionist() { const perfectionistPlugin = await interopDefault( import('eslint-plugin-perfectionist') ); return [ perfectionistPlugin.configs["recommended-natural"], { rules: { "perfectionist/sort-exports": [ "error", { order: "asc", type: "natural" } ], "perfectionist/sort-imports": [ "error", { customGroups: { type: { "qes-core-type": ["^@qes-core/.+"], "qes-type": ["^@qes/.+"], "vue-type": ["^vue$", "^vue-.+", "^@vue/.+"] }, value: { qes: ["^@qes/.+"], "qes-core": ["^@qes-core/.+"], vue: ["^vue$", "^vue-.+", "^@vue/.+"] } }, environment: "node", groups: [ ["external-type", "builtin-type", "type"], "vue-type", "qes-type", "qes-core-type", ["parent-type", "sibling-type", "index-type"], ["internal-type"], "builtin", "vue", "qes", "qes-core", "external", "internal", ["parent", "sibling", "index"], "side-effect", "side-effect-style", "style", "object", "unknown" ], internalPattern: ["^#/.+"], newlinesBetween: "always", order: "asc", type: "natural" } ], "perfectionist/sort-modules": "off", "perfectionist/sort-named-exports": [ "error", { order: "asc", type: "natural" } ], "perfectionist/sort-objects": [ "off", { customGroups: { items: "items", list: "list", children: "children" }, groups: ["unknown", "items", "list", "children"], ignorePattern: ["children"], order: "asc", type: "natural" } ] } } ]; } async function prettier() { const [pluginPrettier] = await Promise.all([ interopDefault(import('eslint-plugin-prettier')) ]); return [ { plugins: { prettier: pluginPrettier }, rules: { "prettier/prettier": "error" } } ]; } async function regexp() { const [pluginRegexp] = await Promise.all([ interopDefault(import('eslint-plugin-regexp')) ]); return [ { plugins: { regexp: pluginRegexp }, rules: { ...pluginRegexp.configs.recommended.rules } } ]; } async function test() { const [pluginTest, pluginNoOnlyTests] = await Promise.all([ interopDefault(import('eslint-plugin-vitest')), // @ts-expect-error - no types interopDefault(import('eslint-plugin-no-only-tests')) ]); return [ { files: [ `**/__tests__/**/*.?([cm])[jt]s?(x)`, `**/*.spec.?([cm])[jt]s?(x)`, `**/*.test.?([cm])[jt]s?(x)`, `**/*.bench.?([cm])[jt]s?(x)`, `**/*.benchmark.?([cm])[jt]s?(x)` ], plugins: { test: { ...pluginTest, rules: { ...pluginTest.rules, ...pluginNoOnlyTests.rules } } }, rules: { "no-console": "off", "node/prefer-global/process": "off", "test/consistent-test-it": [ "error", { fn: "it", withinDescribe: "it" } ], "test/no-identical-title": "error", "test/no-import-node-test": "error", "test/no-only-tests": "error", "test/prefer-hooks-in-order": "error", "test/prefer-lowercase-title": "error" } } ]; } async function typescript() { const [pluginTs, parserTs] = await Promise.all([ interopDefault(import('@typescript-eslint/eslint-plugin')), // @ts-expect-error missing types interopDefault(import('@typescript-eslint/parser')) ]); return [ { files: ["**/*.?([cm])[jt]s?(x)"], languageOptions: { parser: parserTs, parserOptions: { createDefaultProgram: false, ecmaFeatures: { jsx: true }, ecmaVersion: "latest", extraFileExtensions: [".vue"], jsxPragma: "React", project: "./tsconfig.*.json", sourceType: "module" } }, plugins: { "@typescript-eslint": pluginTs }, rules: { ...pluginTs.configs["eslint-recommended"].overrides?.[0].rules, ...pluginTs.configs.strict.rules, "@typescript-eslint/ban-ts-comment": [ "error", { "ts-check": false, "ts-expect-error": "allow-with-description", "ts-ignore": "allow-with-description", "ts-nocheck": "allow-with-description" } ], // '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], "@typescript-eslint/consistent-type-definitions": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-empty-function": [ "error", { allow: ["arrowFunctions", "functions", "methods"] } ], "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-non-null-assertion": "error", "@typescript-eslint/no-unused-expressions": "off", "@typescript-eslint/no-unused-vars": [ "error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" } ], "@typescript-eslint/no-use-before-define": "off", "@typescript-eslint/no-var-requires": "error", "@typescript-eslint/prefer-literal-enum-member": "off", "@typescript-eslint/no-duplicate-enum-values": "off", "@typescript-eslint/no-extraneous-class": "off", "unused-imports/no-unused-vars": "off" } } ]; } async function vue() { const [ pluginVue, parserVue, parserTs, vuejsAccessibility, checkMessageOrigin ] = await Promise.all([ interopDefault(import('eslint-plugin-vue')), interopDefault(import('vue-eslint-parser')), // @ts-expect-error missing types interopDefault(import('@typescript-eslint/parser')), interopDefault(import('eslint-plugin-vuejs-accessibility')), interopDefault(import('./chunks/index.mjs')) ]); const flatEssential = pluginVue.configs?.["flat/essential"] || []; const flatStronglyRecommended = pluginVue.configs?.["flat/strongly-recommended"] || []; const flatRecommended = pluginVue.configs?.["flat/recommended"] || []; return [ ...flatEssential, ...flatStronglyRecommended, ...flatRecommended, { files: ["**/*.vue"], languageOptions: { // globals: { // computed: 'readonly', // defineEmits: 'readonly', // defineExpose: 'readonly', // defineProps: 'readonly', // onMounted: 'readonly', // onUnmounted: 'readonly', // reactive: 'readonly', // ref: 'readonly', // shallowReactive: 'readonly', // shallowRef: 'readonly', // toRef: 'readonly', // toRefs: 'readonly', // watch: 'readonly', // watchEffect: 'readonly', // }, parser: parserVue, parserOptions: { ecmaFeatures: { jsx: true }, extraFileExtensions: [".vue"], parser: parserTs, sourceType: "module" } }, plugins: { vue: pluginVue, "vuejs-accessibility": vuejsAccessibility, "custom-message": checkMessageOrigin }, processor: pluginVue.processors?.[".vue"], rules: { ...pluginVue.configs?.base?.rules, "vue/attribute-hyphenation": [ "error", "always", { ignore: [] } ], "vue/attributes-order": "off", "vue/block-order": "off", "vue/component-name-in-template-casing": ["error", "PascalCase"], "vue/component-options-name-casing": ["error", "PascalCase"], "vue/custom-event-name-casing": ["error", "camelCase"], "vue/define-macros-order": [ "error", { order: [ "defineOptions", "defineProps", "defineEmits", "defineSlots" ] } ], "vue/dot-location": ["error", "property"], "vue/dot-notation": ["error", { allowKeywords: true }], "vue/eqeqeq": ["error", "smart"], "vue/html-closing-bracket-newline": "error", "vue/html-indent": "off", // 'vue/html-indent': ['error', 2], "vue/html-quotes": ["error", "double"], "vue/html-self-closing": [ "error", { html: { component: "always", normal: "never", void: "always" }, math: "always", svg: "always" } ], "vue/max-attributes-per-line": "off", "vue/multi-word-component-names": "off", "vue/multiline-html-element-content-newline": "error", "vue/no-empty-pattern": "off", "vue/no-extra-parens": ["error", "functions"], "vue/no-irregular-whitespace": "error", "vue/no-loss-of-precision": "error", "vue/no-reserved-component-names": "off", "vue/no-restricted-syntax": [ "error", "DebuggerStatement", "LabeledStatement", "WithStatement", // 验证table相关属性 { selector: 'VElement[name="table"]:not(:has(VAttribute[key.name="aria-describedby"]))', message: "<table> \u5FC5\u987B\u5305\u542B aria-describedby \u5C5E\u6027" }, { selector: 'VElement[name="th"]:not(:has(VAttribute[key.name="scope"]))', message: "<th> \u5FC5\u987B\u5305\u542B scope \u5C5E\u6027" }, { selector: 'VElement[name="a"]:has(VAttribute[key.name="target"][value.value="_blank"]):not(:has(VAttribute[key.name="rel"]))', message: 'a\u6807\u7B7E \u4F7F\u7528 target="_blank" \u65F6\u5FC5\u987B\u6DFB\u52A0 rel \u5C5E\u6027' }, { selector: 'VElement[name="a"]:has(VAttribute[key.name="target"][value.value="_blank"]):has(VAttribute[key.name="rel"]):not(:has(VAttribute[key.name="rel"][value.value="noopener"])):not(:has(VAttribute[key.name="rel"][value.value="noreferrer"])):not(:has(VAttribute[key.name="rel"][value.value="noopener noreferrer"])):not(:has(VAttribute[key.name="rel"][value.value="noreferrer noopener"]))', message: 'a\u6807\u7B7E \u4F7F\u7528 target="_blank" \u65F6\uFF0Crel \u5C5E\u6027\u5FC5\u987B\u5305\u542B "noopener" \u6216 "noreferrer"' } ], "vue/no-restricted-v-bind": ["error", "/^v-/"], "vue/no-sparse-arrays": "error", "vue/no-unused-refs": "error", "vue/no-useless-v-bind": "warn", "vue/object-shorthand": [ "error", "always", { avoidQuotes: true, ignoreConstructors: false } ], "vue/one-component-per-file": "error", "vue/prefer-import-from-vue": "error", "vue/prefer-separate-static-class": "error", "vue/prefer-template": "error", "vue/prop-name-casing": ["error", "camelCase"], "vue/require-default-prop": "error", "vue/require-explicit-emits": "error", "vue/require-prop-types": "off", "vue/singleline-html-element-content-newline": "off", "vue/space-infix-ops": "error", "vue/no-undef-properties": "error", "vue/space-unary-ops": ["error", { nonwords: false, words: true }], "vue/v-on-event-hyphenation": [ "error", "always", { autofix: true, ignore: [] } ], // vuejs-accessibility "vuejs-accessibility/alt-text": "error", "vuejs-accessibility/iframe-has-title": "error", "vuejs-accessibility/aria-props": "error", "vuejs-accessibility/no-redundant-roles": "error", // custom plugins "custom-message/check-message-origin": "error" } } ]; } const restrictedImportIgnores = ["**/vite.config.ts"]; const customConfig = [ { files: ["packages/**/**"], ignores: restrictedImportIgnores, rules: { "perfectionist/sort-interfaces": "off", "perfectionist/sort-objects": "off", "prefer-spread": "off", "eslint-comments/no-unlimited-disable": "off" } }, { files: ["**/**.vue"], ignores: restrictedImportIgnores, rules: { "perfectionist/sort-objects": "off" } }, { files: ["**/**.vue", "**/**.ts"], ignores: restrictedImportIgnores, plugins: { "@typescript-eslint": typescriptEslint }, rules: { "@typescript-eslint/no-explicit-any": "warn" } }, { files: ["internal/**/**", "scripts/**/**"], rules: { "no-console": "off" } } ]; async function defineConfig(config = []) { const configs = [ vue(), javascript(), ignores(), prettier(), typescript(), jsonc(), disableds(), importPluginConfig(), node(), perfectionist(), comments(), jsdoc(), test(), regexp(), command(), // turbo(), // 暂时移除,因为有兼容性问题 ...customConfig, ...config ]; const resolved = await Promise.all(configs); return resolved.flat(); } export { defineConfig };