201 lines
5.2 KiB
TypeScript
201 lines
5.2 KiB
TypeScript
import eslint from "@eslint/js";
|
||
import globals from "globals";
|
||
import * as typescriptEslint from "typescript-eslint";
|
||
import pluginVue from "eslint-plugin-vue";
|
||
import vueParser from "vue-eslint-parser";
|
||
import skipFormatting from "@vue/eslint-config-prettier/skip-formatting";
|
||
|
||
export default [
|
||
{
|
||
ignores: [
|
||
"**/node_modules/**",
|
||
"**/dist/**",
|
||
"**/*.min.*",
|
||
"**/auto-imports.d.ts",
|
||
"**/components.d.ts",
|
||
"types/**/*.d.ts",
|
||
],
|
||
},
|
||
|
||
eslint.configs.recommended,
|
||
...pluginVue.configs["flat/recommended"],
|
||
...typescriptEslint.configs.recommended,
|
||
|
||
{
|
||
files: ["**/*.{js,mjs,cjs,ts,mts,cts,vue}"],
|
||
languageOptions: {
|
||
ecmaVersion: "latest",
|
||
sourceType: "module",
|
||
globals: {
|
||
...globals.es2022,
|
||
},
|
||
},
|
||
plugins: {
|
||
vue: pluginVue,
|
||
"@typescript-eslint": typescriptEslint.plugin,
|
||
},
|
||
rules: {
|
||
// 基础规则
|
||
"no-console": ["error", { allow: ["warn", "error", "debug"] }],
|
||
"no-debugger": "error",
|
||
|
||
// ES6+ 规则
|
||
"prefer-const": "error",
|
||
"no-var": "error",
|
||
"object-shorthand": "error",
|
||
|
||
// 最佳实践
|
||
eqeqeq: ["error", "always", { null: "ignore" }],
|
||
"no-multi-spaces": "error",
|
||
"no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }],
|
||
|
||
// 禁用与 TypeScript 冲突的规则
|
||
"no-unused-vars": "off",
|
||
"no-undef": "off",
|
||
"no-redeclare": "off",
|
||
},
|
||
},
|
||
|
||
{
|
||
files: ["src/**/*.{js,ts,vue}"],
|
||
languageOptions: { globals: { ...globals.browser, __APP_INFO__: "readonly" } },
|
||
},
|
||
{
|
||
files: ["*.{js,mjs,cjs,ts}", "mock/**/*.ts"],
|
||
languageOptions: { globals: globals.node },
|
||
rules: { "no-console": "off" },
|
||
},
|
||
{
|
||
files: ["**/*.{js,mjs,cjs}"],
|
||
rules: { "no-undef": "error" },
|
||
},
|
||
|
||
{
|
||
files: ["**/*.vue"],
|
||
languageOptions: {
|
||
parser: vueParser,
|
||
parserOptions: {
|
||
ecmaVersion: "latest",
|
||
sourceType: "module",
|
||
parser: typescriptEslint.parser,
|
||
extraFileExtensions: [".vue"],
|
||
tsconfigRootDir: import.meta.dirname,
|
||
},
|
||
},
|
||
rules: {
|
||
"vue/multi-word-component-names": "off",
|
||
"vue/no-v-html": "off",
|
||
"vue/require-default-prop": "off",
|
||
"vue/require-explicit-emits": "error",
|
||
"vue/no-unused-vars": "error",
|
||
"vue/no-mutating-props": "warn",
|
||
"vue/valid-v-for": "warn",
|
||
"vue/no-template-shadow": "warn",
|
||
// 组件由 unplugin-vue-components 自动注册,ESLint 侧拿不到已注册组件清单
|
||
"vue/no-undef-components": "off",
|
||
"vue/return-in-computed-property": "error",
|
||
"vue/block-order": [
|
||
"error",
|
||
{
|
||
order: ["template", "script", "style"],
|
||
},
|
||
],
|
||
"vue/html-self-closing": [
|
||
"error",
|
||
{
|
||
html: {
|
||
void: "always",
|
||
normal: "never",
|
||
component: "always",
|
||
},
|
||
svg: "always",
|
||
math: "always",
|
||
},
|
||
],
|
||
"vue/component-name-in-template-casing": ["error", "PascalCase"],
|
||
},
|
||
},
|
||
|
||
{
|
||
files: ["**/*.{ts,tsx,mts,cts}"],
|
||
languageOptions: {
|
||
parser: typescriptEslint.parser,
|
||
parserOptions: {
|
||
ecmaVersion: "latest",
|
||
sourceType: "module",
|
||
projectService: true,
|
||
tsconfigRootDir: import.meta.dirname,
|
||
},
|
||
},
|
||
rules: {
|
||
"@typescript-eslint/no-empty-function": "off",
|
||
"@typescript-eslint/no-empty-object-type": "off",
|
||
"@typescript-eslint/no-non-null-assertion": "off",
|
||
"@typescript-eslint/no-unused-expressions": "warn",
|
||
},
|
||
},
|
||
|
||
{
|
||
// Vue 与 TS 共用的脚本规则:同一段代码放在 .ts 或 <script setup lang="ts"> 中要求一致
|
||
files: ["**/*.{ts,tsx,mts,cts,vue}"],
|
||
rules: {
|
||
"@typescript-eslint/ban-ts-comment": [
|
||
"warn",
|
||
{
|
||
"ts-ignore": true,
|
||
"ts-expect-error": "allow-with-description",
|
||
minimumDescriptionLength: 10,
|
||
},
|
||
],
|
||
"@typescript-eslint/no-explicit-any": "warn",
|
||
"@typescript-eslint/no-unused-vars": [
|
||
"warn",
|
||
{
|
||
argsIgnorePattern: "^_",
|
||
varsIgnorePattern: "^_",
|
||
caughtErrorsIgnorePattern: "^_",
|
||
},
|
||
],
|
||
"@typescript-eslint/consistent-type-imports": [
|
||
"error",
|
||
{
|
||
fixStyle: "separate-type-imports",
|
||
prefer: "type-imports",
|
||
},
|
||
],
|
||
"@typescript-eslint/no-import-type-side-effects": "error",
|
||
},
|
||
},
|
||
|
||
{
|
||
files: ["**/*.d.ts"],
|
||
rules: {
|
||
"@typescript-eslint/no-explicit-any": "off",
|
||
"@typescript-eslint/no-unused-vars": "off",
|
||
},
|
||
},
|
||
|
||
{
|
||
// 先在基础异步边界试点,避免全仓同时切换 typed 规则。
|
||
files: [
|
||
"src/composables/usePageTable.ts",
|
||
"src/utils/realtime/client.ts",
|
||
"src/views/workflow/components/FormDetail.vue",
|
||
],
|
||
languageOptions: {
|
||
parserOptions: {
|
||
projectService: true,
|
||
tsconfigRootDir: import.meta.dirname,
|
||
extraFileExtensions: [".vue"],
|
||
},
|
||
},
|
||
rules: {
|
||
"@typescript-eslint/no-floating-promises": ["warn", { ignoreVoid: true }],
|
||
"@typescript-eslint/no-misused-promises": "warn",
|
||
"@typescript-eslint/await-thenable": "warn",
|
||
},
|
||
},
|
||
|
||
skipFormatting,
|
||
];
|