2025-12-05 10:17:26 +08:00
|
|
|
|
// https://eslint.org/docs/latest/use/configure/configuration-files-new
|
|
|
|
|
|
|
|
|
|
|
|
// 基础ESLint配置
|
2025-12-11 17:13:37 +08:00
|
|
|
|
import eslint from '@eslint/js'
|
|
|
|
|
|
import globals from 'globals'
|
2025-12-05 10:17:26 +08:00
|
|
|
|
// TypeScript支持
|
2025-12-11 17:13:37 +08:00
|
|
|
|
import * as typescriptEslint from 'typescript-eslint'
|
2025-12-05 10:17:26 +08:00
|
|
|
|
// Vue支持
|
2025-12-11 17:13:37 +08:00
|
|
|
|
import pluginVue from 'eslint-plugin-vue'
|
|
|
|
|
|
import vueParser from 'vue-eslint-parser'
|
2025-12-05 10:17:26 +08:00
|
|
|
|
// 代码风格与格式化
|
2025-12-11 17:13:37 +08:00
|
|
|
|
import configPrettier from 'eslint-config-prettier'
|
|
|
|
|
|
import prettierPlugin from 'eslint-plugin-prettier'
|
2025-12-05 10:17:26 +08:00
|
|
|
|
|
|
|
|
|
|
// 解析自动导入配置
|
2025-12-11 17:13:37 +08:00
|
|
|
|
import fs from 'node:fs'
|
|
|
|
|
|
let autoImportGlobals = {}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
try {
|
|
|
|
|
|
autoImportGlobals =
|
2025-12-11 17:13:37 +08:00
|
|
|
|
JSON.parse(fs.readFileSync('./.eslintrc-auto-import.json', 'utf-8')).globals || {}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// 文件不存在或解析错误时使用空对象
|
2025-12-11 17:13:37 +08:00
|
|
|
|
console.warn('Could not load auto-import globals', error)
|
2025-12-05 10:17:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Element Plus组件
|
|
|
|
|
|
const elementPlusComponents = {
|
|
|
|
|
|
// Element Plus 组件添加为全局变量,避免 no-undef 报错
|
2025-12-11 17:13:37 +08:00
|
|
|
|
ElInput: 'readonly',
|
|
|
|
|
|
ElSelect: 'readonly',
|
|
|
|
|
|
ElSwitch: 'readonly',
|
|
|
|
|
|
ElCascader: 'readonly',
|
|
|
|
|
|
ElInputNumber: 'readonly',
|
|
|
|
|
|
ElTimePicker: 'readonly',
|
|
|
|
|
|
ElTimeSelect: 'readonly',
|
|
|
|
|
|
ElDatePicker: 'readonly',
|
|
|
|
|
|
ElTreeSelect: 'readonly',
|
|
|
|
|
|
ElText: 'readonly',
|
|
|
|
|
|
ElRadioGroup: 'readonly',
|
|
|
|
|
|
ElCheckboxGroup: 'readonly',
|
|
|
|
|
|
ElOption: 'readonly',
|
|
|
|
|
|
ElRadio: 'readonly',
|
|
|
|
|
|
ElCheckbox: 'readonly',
|
|
|
|
|
|
ElInputTag: 'readonly',
|
|
|
|
|
|
ElForm: 'readonly',
|
|
|
|
|
|
ElFormItem: 'readonly',
|
|
|
|
|
|
ElTable: 'readonly',
|
|
|
|
|
|
ElTableColumn: 'readonly',
|
|
|
|
|
|
ElButton: 'readonly',
|
|
|
|
|
|
ElDialog: 'readonly',
|
|
|
|
|
|
ElPagination: 'readonly',
|
|
|
|
|
|
ElMessage: 'readonly',
|
|
|
|
|
|
ElMessageBox: 'readonly',
|
|
|
|
|
|
ElNotification: 'readonly',
|
|
|
|
|
|
ElTree: 'readonly'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
|
|
|
|
|
|
export default [
|
|
|
|
|
|
// 忽略文件配置
|
|
|
|
|
|
{
|
|
|
|
|
|
ignores: [
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'**/node_modules/**',
|
|
|
|
|
|
'**/dist/**',
|
|
|
|
|
|
'**/*.min.*',
|
|
|
|
|
|
'**/auto-imports.d.ts',
|
|
|
|
|
|
'**/components.d.ts'
|
|
|
|
|
|
]
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 基础 JavaScript 配置
|
|
|
|
|
|
eslint.configs.recommended,
|
|
|
|
|
|
|
|
|
|
|
|
// Vue 推荐配置
|
2025-12-11 17:13:37 +08:00
|
|
|
|
...pluginVue.configs['flat/recommended'],
|
2025-12-05 10:17:26 +08:00
|
|
|
|
|
|
|
|
|
|
// TypeScript 推荐配置
|
|
|
|
|
|
...typescriptEslint.configs.recommended,
|
|
|
|
|
|
|
|
|
|
|
|
// 全局配置
|
|
|
|
|
|
{
|
|
|
|
|
|
// 指定要检查的文件
|
2025-12-11 17:13:37 +08:00
|
|
|
|
files: ['**/*.{js,mjs,cjs,ts,mts,cts,vue}'],
|
2025-12-05 10:17:26 +08:00
|
|
|
|
languageOptions: {
|
2025-12-11 17:13:37 +08:00
|
|
|
|
ecmaVersion: 'latest',
|
|
|
|
|
|
sourceType: 'module',
|
2025-12-05 10:17:26 +08:00
|
|
|
|
globals: {
|
|
|
|
|
|
...globals.browser, // 浏览器环境全局变量
|
|
|
|
|
|
...globals.node, // Node.js 环境全局变量
|
|
|
|
|
|
...globals.es2022, // ES2022 全局对象
|
|
|
|
|
|
...autoImportGlobals, // 自动导入的 API 函数
|
|
|
|
|
|
...elementPlusComponents, // Element Plus 组件
|
|
|
|
|
|
// 全局类型定义,解决 TypeScript 中定义但 ESLint 不识别的问题
|
2025-12-11 17:13:37 +08:00
|
|
|
|
PageQuery: 'readonly',
|
|
|
|
|
|
PageResult: 'readonly',
|
|
|
|
|
|
OptionType: 'readonly',
|
|
|
|
|
|
ApiResponse: 'readonly',
|
|
|
|
|
|
ExcelResult: 'readonly',
|
|
|
|
|
|
TagView: 'readonly',
|
|
|
|
|
|
AppSettings: 'readonly',
|
|
|
|
|
|
__APP_INFO__: 'readonly'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
plugins: {
|
|
|
|
|
|
vue: pluginVue,
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'@typescript-eslint': typescriptEslint.plugin
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
rules: {
|
|
|
|
|
|
// 基础规则
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
|
|
|
|
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
|
|
|
|
|
// 添加这一行来强制使用单引号
|
|
|
|
|
|
quotes: ['error', 'single'],
|
|
|
|
|
|
semi: ['error', 'never'],
|
|
|
|
|
|
'comma-dangle': ['error', 'never'],
|
|
|
|
|
|
|
|
|
|
|
|
// ES6+ 规则SEWDvv
|
|
|
|
|
|
'prefer-const': 'error',
|
|
|
|
|
|
'no-var': 'error',
|
|
|
|
|
|
'object-shorthand': 'error',
|
2025-12-05 10:17:26 +08:00
|
|
|
|
|
|
|
|
|
|
// 最佳实践
|
2025-12-11 17:13:37 +08:00
|
|
|
|
eqeqeq: 'off',
|
|
|
|
|
|
'no-multi-spaces': 'error',
|
|
|
|
|
|
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }],
|
2025-12-05 10:17:26 +08:00
|
|
|
|
|
|
|
|
|
|
// 禁用与 TypeScript 冲突的规则
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'no-unused-vars': 'off',
|
|
|
|
|
|
'no-undef': 'off',
|
|
|
|
|
|
'no-redeclare': 'off',
|
|
|
|
|
|
'@typescript-eslint/ban-ts-comment': 'off'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Vue 文件特定配置
|
|
|
|
|
|
{
|
2025-12-11 17:13:37 +08:00
|
|
|
|
files: ['**/*.vue'],
|
2025-12-05 10:17:26 +08:00
|
|
|
|
languageOptions: {
|
|
|
|
|
|
parser: vueParser,
|
|
|
|
|
|
parserOptions: {
|
2025-12-11 17:13:37 +08:00
|
|
|
|
ecmaVersion: 'latest',
|
|
|
|
|
|
sourceType: 'module',
|
2025-12-05 10:17:26 +08:00
|
|
|
|
parser: typescriptEslint.parser,
|
2025-12-11 17:13:37 +08:00
|
|
|
|
extraFileExtensions: ['.vue'],
|
|
|
|
|
|
tsconfigRootDir: __dirname
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
rules: {
|
|
|
|
|
|
// Vue 规则
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'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': 'off',
|
|
|
|
|
|
'vue/valid-v-for': 'warn',
|
|
|
|
|
|
'vue/no-template-shadow': 'warn',
|
|
|
|
|
|
'vue/return-in-computed-property': 'warn',
|
|
|
|
|
|
'vue/block-order': [
|
|
|
|
|
|
'error',
|
2025-12-05 10:17:26 +08:00
|
|
|
|
{
|
2025-12-11 17:13:37 +08:00
|
|
|
|
order: ['template', 'script', 'style']
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
],
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'vue/html-self-closing': [
|
|
|
|
|
|
'error',
|
2025-12-05 10:17:26 +08:00
|
|
|
|
{
|
|
|
|
|
|
html: {
|
2025-12-11 17:13:37 +08:00
|
|
|
|
void: 'always',
|
|
|
|
|
|
normal: 'never',
|
|
|
|
|
|
component: 'always'
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
2025-12-11 17:13:37 +08:00
|
|
|
|
svg: 'always',
|
|
|
|
|
|
math: 'always'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
],
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
|
|
|
|
|
|
'@typescript-eslint/no-explicit-any': 'off'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// TypeScript 文件特定配置
|
|
|
|
|
|
{
|
2025-12-11 17:13:37 +08:00
|
|
|
|
files: ['**/*.{ts,tsx,mts,cts}'],
|
2025-12-05 10:17:26 +08:00
|
|
|
|
languageOptions: {
|
|
|
|
|
|
parser: typescriptEslint.parser,
|
|
|
|
|
|
parserOptions: {
|
2025-12-11 17:13:37 +08:00
|
|
|
|
ecmaVersion: 'latest',
|
|
|
|
|
|
sourceType: 'module',
|
|
|
|
|
|
project: './tsconfig.json',
|
|
|
|
|
|
tsconfigRootDir: __dirname
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
rules: {
|
|
|
|
|
|
// TypeScript 规则
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'@typescript-eslint/no-explicit-any': 'off', // 允许使用any类型,方便开发
|
|
|
|
|
|
'@typescript-eslint/no-empty-function': 'off',
|
|
|
|
|
|
'@typescript-eslint/no-empty-object-type': 'off',
|
|
|
|
|
|
'@typescript-eslint/ban-ts-comment': 'off',
|
|
|
|
|
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
|
|
|
|
'@typescript-eslint/no-unused-vars': 'warn', // 降级为警告
|
|
|
|
|
|
'@typescript-eslint/no-unused-expressions': 'warn', // 降级为警告
|
|
|
|
|
|
'@typescript-eslint/consistent-type-imports': 'off', // 关闭强制使用type import
|
|
|
|
|
|
'@typescript-eslint/no-import-type-side-effects': 'error'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// .d.ts 文件配置
|
|
|
|
|
|
{
|
2025-12-11 17:13:37 +08:00
|
|
|
|
files: ['**/*.d.ts'],
|
2025-12-05 10:17:26 +08:00
|
|
|
|
rules: {
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'@typescript-eslint/no-explicit-any': 'off',
|
|
|
|
|
|
'@typescript-eslint/no-unused-vars': 'off'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// CURD 组件配置
|
|
|
|
|
|
{
|
2025-12-11 17:13:37 +08:00
|
|
|
|
files: ['**/components/CURD/**/*.{ts,vue}'],
|
2025-12-05 10:17:26 +08:00
|
|
|
|
rules: {
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'no-unused-vars': 'off',
|
|
|
|
|
|
'@typescript-eslint/no-unused-vars': 'off',
|
|
|
|
|
|
'@typescript-eslint/no-explicit-any': 'off'
|
|
|
|
|
|
}
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Prettier 集成(必须放在最后)
|
|
|
|
|
|
{
|
|
|
|
|
|
plugins: {
|
2025-12-11 17:13:37 +08:00
|
|
|
|
prettier: prettierPlugin // 将 Prettier 的输出作为 ESLint 的问题来报告
|
2025-12-05 10:17:26 +08:00
|
|
|
|
},
|
|
|
|
|
|
rules: {
|
|
|
|
|
|
...configPrettier.rules,
|
2025-12-11 17:13:37 +08:00
|
|
|
|
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
|
|
|
|
|
|
'arrow-body-style': 'off',
|
|
|
|
|
|
'prefer-arrow-callback': 'off'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|