import eslint from '@eslint/js'; import tseslint from 'typescript-eslint'; import pluginVue from 'eslint-plugin-vue'; import parserVue from 'vue-eslint-parser'; import jsdoc from 'eslint-plugin-jsdoc'; import globals from 'globals'; import configPrettier from 'eslint-config-prettier'; import { defineConfig } from 'eslint/config'; /** 得到vue版本 (如:3.2.45) */ const vueVersions = '3.4.27'; const vueVersionsNumb = 3.3; /** 是否有TS验证规则 */ const tsVerify = true; export default defineConfig( { ignores: ['**/src/sdk/tstudy_digital_pen/src/*.js'], }, eslint.configs.recommended, configPrettier, ...pluginVue.configs['flat/recommended'], ...tseslint.configs.strict, ...tseslint.configs.stylistic, { languageOptions: { globals: { ...globals.node, ...globals.browser, ElMessage: 'readonly', ElLoading: 'readonly', ElMessageBox: 'readonly', __APP_VERSION_TIMESTAMP__: 'readonly', // APP版本号时间戳(在vite.config中配置) }, }, plugins: { jsdoc, }, rules: { ...getBaseRules(), ...getJsDocRules(), }, }, { files: ['**/*.ts', '**/*.cts', '**/*.mts', '**/*.ctsx', '**/*.mtsx', '**/*.tsx'], languageOptions: { parser: tseslint.parser, parserOptions: { sourceType: 'module', }, }, plugins: { '@typescript-eslint': tseslint.plugin, }, rules: { ...getTypescriptRules(), }, }, { files: ['**/*.d.ts'], rules: { 'init-declarations': 'off', }, }, { files: ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.cjsx', '**/*.mjsx', '**/*.jsx'], rules: { '@typescript-eslint/no-require-imports': 'off', '@typescript-eslint/no-var-requires': 'off', }, }, { files: ['**/*.vue'], languageOptions: { globals: {}, parser: parserVue, ecmaVersion: 'latest', // 启用es2020的语法包含以下版本 2015(同6)、2016(同7)、2017(同8)、2018(同9)、2019(同10)、2020(同11)、2021(同为 12)或 2022(与 13 相同)以使用基于年份的命名。您还可以设置 “latest” 以使用最新支持的版本 sourceType: 'module', parserOptions: { extraFileExtensions: ['.vue'], parser: tseslint.parser, sourceType: 'module', // project: true, // tsconfigRootDir: import.meta.dirname, ecmaFeatures: { jsx: true, impliedStrict: true, // 启用全局严格模式 }, }, }, plugins: { vue: pluginVue, '@typescript-eslint': tseslint.plugin, }, processor: pluginVue.processors['.vue'], rules: { ...getVueRules(), ...getTypescriptRules(), }, }, { files: ['**/*.js'], rules: { 'no-undef': 'error', 'no-unused-vars': 'error', 'default-param-last': 'error', 'init-declarations': ['error', 'always'], 'no-empty-function': 'error', 'no-shadow': 'error', '@typescript-eslint/no-unused-expressions': 'off', }, } ); /** * 得到eslint的规则 */ function getBaseRules() { return { /** *************************************************** 这些规则与代码中可能的逻辑错误有关 */ // 强制数组方法的回调函数中有 return 语句 'array-callback-return': 'error', // 强制在子类构造函数中用super()调用父类构造函数,TypeScrip的编译器也会提示 'constructor-super': 'error', // 强制 “for” 循环中更新子句的计数器朝着正确的方向移动 'for-direction': 'error', // 强制在 getter 属性中出现一个 return 语句。每个 getter 都期望有返回值。 'getter-return': 'error', // 禁止使用异步函数作为 Promise executor 'no-async-promise-executor': 'error', // 不允许await在循环体内使用。 'no-await-in-loop': 'error', // 禁止修改类声明的变量 'no-class-assign': 'error', // 针对试图与-0进行比较的代码发出警告,因为这不会按预期工作。也就是说,像x === -0这样的代码将通过+0和-0。作者可能打算 Object.is(x,-0)。 'no-compare-neg-zero': 'error', // 禁止条件表达式中出现赋值操作符 'no-cond-assign': 'error', // 禁止修改 const 声明的变量 'no-const-assign': 'error', // 将始终评估为真或假的比较以及始终短路或从不短路的逻辑表达式 ( ||, &&, ??) 都可能表明程序员错误 'no-constant-binary-expression': 'error', // [对应 vue/no-constant-condition]禁止在条件中使用常量表达式 [if (false) {} 错] [if (aa===false) {} 对] 'no-constant-condition': 'error', // 不允许从构造函数返回值 'no-constructor-return': 'error', // 禁止在正则表达式中使用控制字符 :new RegExp("\x1f") 'no-control-regex': 'error', // 禁用 debugger 'no-debugger': 'error', // 禁止 function 定义中出现重名参数 'no-dupe-args': 'error', // 禁止类成员中出现重复的名称 // 'no-dupe-class-members': 'error', // 不允许 if-else-if 链中的重复条件 'no-dupe-else-if': 'error', // 禁止对象字面量中出现重复的 key 'no-dupe-keys': 'error', // 禁止重复的 case 标签 'no-duplicate-case': 'error', // 不允许复制模块的进口 'no-duplicate-imports': 'error', // 禁止在正则表达式中使用空字符集 (/^abc[]/) 'no-empty-character-class': 'error', // [对应 vue/no-empty-pattern]禁止使用空解构模式no-empty-pattern 'no-empty-pattern': 'error', // 禁止对 catch 子句的参数重新赋值 'no-ex-assign': 'error', // 禁止 case 语句落空 'no-fallthrough': 'error', // 禁止对 function 声明重新赋值 'no-func-assign': 'error', // 禁止对 function 声明重新赋值 'no-import-assign': 'error', // 禁止在嵌套的块中出现 function 或 var 声明 'no-inner-declarations': ['error', 'both'], // 禁止 RegExp 构造函数中无效的正则表达式字符串 'no-invalid-regexp': 'error', // 禁止在字符串和注释之外不规则的空白 'no-irregular-whitespace': ['error', { skipStrings: true }], // 不允许丢失精度的数值 'no-loss-of-precision': 'error', // 不允许在字符类语法中出现由多个代码点组成的字符, 因为Unicode 包括由多个代码点组成的字符。RegExp 字符类语法 (/[abc]/) 不能处理由多个代码点组成的字符 'no-misleading-character-class': 'error', // 不允许在字符类语法中出现由多个代码点组成的字符, 因为Unicode 包括由多个代码点组成的字符。RegExp 字符类语法 (/[abc]/) 不能处理由多个代码点组成的字符 'no-new-native-nonconstructor': 'error', // 禁止在不能使用new的变量前使用new // 禁止 Symbol 的构造函数 'no-new-symbol': 'error', // 禁止把全局对象 (Math 和 JSON) 作为函数调用 错误:var math = Math(); 'no-obj-calls': 'error', // 不允许从 Promise 执行器函数返回值 'no-promise-executor-return': 'error', // 禁止直接使用 Object.prototypes的内置属性 例如,foo.hasOwnProperty("bar") 应该替换为 Object.prototype.hasOwnProperty.call(foo, "bar") 'no-prototype-builtins': 'error', // 禁止自我赋值 'no-self-assign': 'error', // 禁止自身比较 'no-self-compare': 'error', // 虽然从 setter 返回值不会产生错误,但返回的值将被忽略。因此,从 setter 返回值要么是不必要的,要么是可能的错误,因为不能使用返回的值。 'no-setter-return': 'error', // [对应 vue/no-sparse-arrays]禁用稀疏数组 'no-sparse-arrays': 'error', // 警告常规字符串包含看起来像模板字面占位符的内容。"Hello ${name}!"; 'no-template-curly-in-string': 'error', // 禁止在构造函数中,在调用 super() 之前使用 this 或 super 'no-this-before-super': 'error', // 禁用未声明的变量,除非它们在 /*global */ 注释中被提到 'no-undef': tsVerify ? 'off' : 'error', // 禁止出现令人困惑的多行表达式 'no-unexpected-multiline': 'error', // 禁用一成不变的循环条件 'no-unmodified-loop-condition': 'error', // 禁止在return、throw、continue 和 break语句之后出现不可达代码 'no-unreachable': 'error', // 禁止无法访问的循环 'no-unreachable-loop': 'error', // 禁止在 finally 语句块中出现控制流语句 'no-unsafe-finally': 'error', // 禁止否定关系运算符的左操作数 'no-unsafe-negation': ['error', { enforceForOrderingRelations: true }], // 禁止在不允许使用值的上下文中使用[可选链?.] 如(undefined) 'no-unsafe-optional-chaining': 'error', // 禁止未使用的私有类成员 'no-unused-private-class-members': 'error', // 禁止出现未使用过的变量 'no-unused-vars': tsVerify ? 'off' : 'error', // 不允许在变量定义之前使用它们 'no-use-before-define': ['error', { functions: false, classes: true, variables: true }], // 禁止在正则表达式中使用无用的反向引用 'no-useless-backreference': 'error', // 禁止由于 await 或 yield的使用而可能导致出现竞态条件的赋值 'require-atomic-updates': ['error', { allowProperties: true }], // 不允许比较"NaN"。判断数字是否是NaN,得用isNaN 'use-isnan': 'error', // 强制 typeof 表达式与有效的字符串进行比较 'valid-typeof': 'error', /** *************************************************** 这些规则建议了不同的做事方式 */ // 定义对象的set存取器属性时,强制定义get 'accessor-pairs': ['error', { setWithoutGet: true, getWithoutSet: true }], // 要求箭头函数体使用大括号 'arrow-body-style': ['off', 'as-needed'], // 强制把变量的使用限制在其定义的作用域范围内 'block-scoped-var': 'error', // [对应 vue/camelcase] 强制执行驼峰命名约定 camelcase: 'off', // 注释 大写字母开头,不推荐 注释的代码会报错 'capitalized-comments': 'off', // 如果一个类方法没有使用this,它有时可以变成一个静态函数。如果将该方法转换为静态函数,那么调用该特定方法的类的实例也必须转换为静态调用 'class-methods-use-this': 'off', // 限制圈复杂度,也就是类似if else能连续接多少个 complexity: 'off', // 要求 return 语句要么总是指定返回的值,要么不指定 'consistent-return': 'error', // 用于指统一在回调函数中指向this的变量名, var that = this; that不能指向其他任何值,this也不能赋值给that以外的其他值 'consistent-this': ['error', 'that'], // 强制所有控制语句使用一致的括号风格 curly: ['error', 'all'], // switch 语句强制 default 分支,也可添加 // no default 注释取消此次警告 'default-case': 'error', // 将 switch 语句中的缺省子句强制为最后一个 'default-case-last': 'error', // 将默认参数强制放在最后 'default-param-last': tsVerify ? 'off' : 'error', // [对应 vue/dot-notation]强制使用.号取属性 'dot-notation': 'error', // [对应 vue/eqeqeq]使用 === 替代 == allow-null允许null和undefined== eqeqeq: ['error', 'always'], // 要求函数名称与它们所分配的变量或属性的名称相匹配 'func-name-matching': 'error', // 强制使用命名的 function 表达式 'func-names': ['error', 'always', { generators: 'as-needed' }], // 强制一致地使用函数声明或函数表达式,方法定义风格 'func-style': ['error', 'declaration', { allowArrowFunctions: true }], // 强制如果一个属性有一个 getter 和一个 setter,那么 setter 应该在 getter 之后定义 'grouped-accessor-pairs': ['error', 'getBeforeSet'], // 要求 for-in 循环中有一个 if 语句 'guard-for-in': 'off', // 禁止使用指定的标识符 'id-denylist': 'off', // 强制标识符的最小和最大长度 (变量名长度) 'id-length': 'off', // 要求标识符匹配一个指定的正则表达式 'id-match': 'off', // 要求或禁止 var 声明中的初始化(初值) 'init-declarations': tsVerify ? 'off' : ['error', 'always'], // 要求或禁止逻辑赋值逻辑运算符速记 'logical-assignment-operators': ['error', 'never'], // 强制实施每个文件的最大类数 'max-classes-per-file': 'off', // 强制执行嵌套块的最大深度,以降低代码复杂度。"max"(默认为4) 'max-depth': ['off', { max: 6 }], // 强制文件的最大行数 'max-lines': 'off', // 强制文件的最大行数 'max-lines-per-function': 'off', // 强制回调函数最大嵌套深度 5层 'max-nested-callbacks': ['off', { max: 5 }], // 强制 function 定义中最多允许的参数数量 'max-params': ['off', { max: 12 }], // 强制 function 块最多允许的的语句数量 'max-statements': 'off', // 强化多行评论的特定风格。 'multiline-comment-style': 'off', // 要求构造函数首字母大写 (要求调用 new 操作符时有首字母大小的函数,允许调用首字母大写的函数时没有 new 操作符。) 'new-cap': ['error', { newIsCap: true, capIsNew: false }], // 禁用 alert、confirm 和 prompt 'no-alert': 'error', // 禁止使用 Array 构造函数 'no-array-constructor': 'error', // 禁用按位运算符 'no-bitwise': 'error', // 禁用 arguments.caller 或 arguments.callee 'no-caller': 'error', // 不允许在 case 子句中使用词法声明 'no-case-declarations': 'error', // 禁用 console 'no-console': 'off', // 禁用 continue 语句 'no-continue': 'error', // 禁止删除变量 'no-delete-var': 'error', // 禁止除法操作符显式的出现在正则表达式开始的位置 'no-div-regex': 'error', // 禁止 if 语句中有 return 之后有 else 'no-else-return': 'off', // 禁止空语句块 'no-empty': ['error', { allowEmptyCatch: true }], // 禁止出现空函数. 如果一个函数包含了一条注释,它将不会被认为有问题。 'no-empty-function': tsVerify ? 'off' : 'error', // 禁止空静态块 'no-empty-static-block': 'error', // 禁止在没有类型检查操作符的情况下与 null 进行比较 'no-eq-null': 'error', // 禁用 eval() 'no-eval': 'error', // 禁止扩展原生类型 'no-extend-native': ['error', { exceptions: ['Object', 'Array'] }], // 禁止不必要的 .bind() 调用 'no-extra-bind': 'error', // 禁止不必要的布尔转换 'no-extra-boolean-cast': 'error', // 禁用不必要的标签 'no-extra-label': 'error', // 此规则不允许修改只读全局变量。 'no-global-assign': 'error', // 禁止使用短符号进行类型转换(!!fOO) 'no-implicit-coercion': 'error', // 禁止在全局范围内使用 var 和命名的 function 声明 'no-implicit-globals': 'error', // 禁止使用类似 eval() 的方法 'no-implied-eval': 'error', // 禁止在代码行后使用内联注释 'no-inline-comments': 'off', // 禁止 this 关键字出现在类和类对象之外 'no-invalid-this': 'error', // 禁用 __iterator__ 属性 'no-iterator': 'error', // 不允许标签与变量同名 'no-label-var': 'error', // 禁用标签语句 'no-labels': 'error', // 禁用不必要的嵌套块 'no-lone-blocks': 'error', // 禁止 if 作为唯一的语句出现在 else 语句中 'no-lonely-if': 'off', // 禁止在循环中出现 function 声明和表达式 'no-loop-func': 'error', // 禁用魔术数字(3.14什么的用常量代替) 'no-magic-numbers': 'off', // 不允许在单个语句中使用多个分配。a = b = c = d; 'no-multi-assign': 'error', // 禁止使用多行字符串,在 JavaScript 中,可以在新行之前使用斜线创建多行字符串 'no-multi-str': 'error', // 不允许否定的表达式 'no-negated-condition': 'off', // 不允许使用嵌套的三元表达式 var foo = bar ? baz : qux === quxx ? bing : bam; 'no-nested-ternary': 'off', // 禁止在非赋值或条件语句中使用 new 操作符 'no-new': 'off', // 禁止对 Function 对象使用 new 操作符 'no-new-func': 'error', // 禁止对 String,Number 和 Boolean 使用 new 操作符 'no-new-wrappers': 'error', // 禁止字符串文本中的序列并转义序列\8\9 'no-nonoctal-decimal-escape': 'error', // 通常不鼓励使用构造函数来构造新的空对象,而支持对象文字表示法,因为简洁,并且全局可以重新定义。 例外情况是,当构造函数用于有意包装作为参数传递的指定值时 'no-object-constructor': 'error', // 禁用八进制字面量 'no-octal': 'error', // 禁止在字符串中使用八进制转义序列 'no-octal-escape': 'error', // 不允许对 function 的参数进行重新赋值 'no-param-reassign': 'error', // 禁止使用一元操作符 ++ 和 -- 'no-plusplus': 'off', // 禁用 __proto__ 属性 'no-proto': 'error', // 禁止使用 var 多次声明同一变量 'no-redeclare': 'error', // 禁止正则表达式字面量中出现多个空格 'no-regex-spaces': 'error', // 禁止在导出中指定名称 'no-restricted-exports': 'off', // 禁止在导出中指定名称 restrictedNamedExports中就是限制导出的名称 禁用特定的全局变量 'no-restricted-globals': ['error', { name: 'event', message: 'event请在方法的参数中定义event' }], // 禁止加载指定的模块 paths中就是需要禁止加载的模块 'no-restricted-imports': ['off', { paths: ['import1', 'import2'] }], // 禁止某些对象上的某些属性 如果省略对象名称,则不允许所有对象使用该属性;如果省略属性名称,则不允许访问给定对象的任何属性 'no-restricted-properties': [ 'off', { object: '对象名称', property: '对象对象下的属性名称', message: '提示消息', }, ], // 禁止使用特定的语法 'no-restricted-syntax': ['off', { selector: '语法', message: '提示消息' }], // 禁止在返回语句中赋值 (return foo = bar + 2; 错误) 'no-return-assign': 'error', // 禁止使用 javascript: url 'no-script-url': 'error', // 禁用逗号操作符 'no-sequences': 'error', // 禁止变量声明与外层作用域的变量同名 'no-shadow': tsVerify ? 'off' : 'error', // 禁止覆盖受限制的标识符 'no-shadow-restricted-names': 'error', // 不允许使用三元操作符 'no-ternary': 'off', // 禁止抛出非异常字面量 'no-throw-literal': 'error', // 禁止将变量初始化为undefined 'no-undef-init': 'off', // 禁止将 undefined 作为标识符 'no-undefined': 'off', // 禁止标识符中有悬空下划线_bar 'no-underscore-dangle': 'off', // 禁止在有比三元操作符更简单表达式时使用三元操作符 'no-unneeded-ternary': 'error', // 禁止出现未使用过的表达式 'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }], // 禁用未使用过的标签 'no-unused-labels': 'error', // 禁止不必要的 .call() 和 .apply() 'no-useless-call': 'error', // 禁止不必要的 catch 子句 'no-useless-catch': 'error', // 禁止不必要的计算性能键对象的文字 'no-useless-computed-key': 'error', // [对应 vue/no-useless-concat]禁止不必要的字符串字面量或模板字面量的连接 'no-useless-concat': 'error', // ES2015 会提供默认的类构造函数。因此,没有必要提供一个空构造函数或一个简单地委托给它的父类的构造函数, 'no-useless-constructor': 'error', // 禁用不必要的转义字符 'no-useless-escape': 'error', // 不允许将导入、导出和解构分配重命名为相同的名称。 'no-useless-rename': 'error', // 禁止冗余返回语句 'no-useless-return': 'error', // 要求使用 let 或 const 而不是 var 'no-var': 'error', // 禁用 void 操作符 'no-void': 'error', // 禁止在注释中使用特定的警告术语 'no-warning-comments': 'off', // 禁用 with 语句 'no-with': 'error', // 要求或禁止对象字面量中方法和属性使用简写语法 'object-shorthand': ['error', 'always'], // 强制函数中的变量要么一起声明要么分开声明 'one-var': ['error', 'never'], // 要求或禁止在可能的情况下要求使用简化的赋值操作符 'operator-assignment': ['error', 'always'], // 要求使用箭头函数作为回调 'prefer-arrow-callback': 'error', // 要求使用 const 声明那些声明后不再被修改的变量 'prefer-const': 'error', // 优先使用数组和对象解构 'prefer-destructuring': 'off', // 禁止使用 有利于运营商的Math.pow() 'prefer-exponentiation-operator': 'error', // 强制在正则表达式中使用命名捕获组 'prefer-named-capture-group': 'off', // 禁止调用parseInt()或Number.parseInt()使用两个参数调用:一个字符串; 和2(二进制),8(八进制)或16(十六进制)的基数选项。 'prefer-numeric-literals': 'error', // 禁止使用Object.prototype.hasOwnProperty.call() 而应该使用Object.hasOwn() 'prefer-object-has-own': 'error', // 优先使用扩展("...")而不是Object.assign 'prefer-object-spread': 'error', // 确保承诺只被Error对象拒绝。 'prefer-promise-reject-errors': 'off', // 不允许使用构造函数创建正则表达式 'prefer-regex-literals': 'off', // 禁止使用 arguments 而应该使用 ...args 'prefer-rest-params': 'error', // 要求使用扩展运算符而非 .apply() 'prefer-spread': 'error', // [对应 vue/prefer-template]要求使用模板字面量而非字符串连接 'prefer-template': 'error', // 强制在parseInt()使用基数参数 radix: 'off', // 禁止无用的赋值 'no-useless-assignment': 'off', // 异步函数必须具有await表达式 'require-await': 'error', // 在正则表达式上强制使用标志 'require-unicode-regexp': 'off', // 要求generator 函数内有 yield 'require-yield': 'error', // 强制模块内的 import 排序 'sort-imports': ['error', { ignoreDeclarationSort: true }], // 所有属性定义并验证所有变量是按字母顺序排序的。 'sort-keys': 'off', // 要求同一个声明块中的变量按顺序排列 'sort-vars': 'error', // 要求或禁止使用严格模式指令 strict: ['error', 'global'], // var foo = Symbol("some description"); 一定要有描述 'symbol-description': 'error', // 要求所有的 var 声明出现在它们所在的作用域顶部 'vars-on-top': 'error', // 要求或禁止 “Yoda” 条件 yoda: 'error', /** *************************************************** 这些规则关心代码的外观,而不是它的执行方式 */ // 强制行注释可以位于代码上方或旁边。该规则有助于团队保持一致的风格。 'line-comment-position': 'off', // 要求或不允许 Unicode 字节顺序标记 'unicode-bom': ['error', 'never'], }; } /** * 得到规则对象 */ function getVueRules() { const v2v3 = {}; const v2 = {}; const v3 = {}; const rest = {}; /** *************************************************** 基本规则(启用正确的 ESLint 解析) */ // 支持中的注释指令 v2v3['vue/comment-directive'] = 'error'; // 规则将查找 JSX 中使用的变量,并将它们标记为已使用 v2v3['vue/jsx-uses-vars'] = 'error'; /** *************************************************** 优先级 A:基本(错误预防) */ // 此规则要求组件名称始终是多字的,但根组件除外,以及 Vue 提供的内置组件,例如或 。这可防止与现有和未来的 HTML 元素发生冲突,因为所有 HTML 元素都是一个词 v2v3['vue/multi-word-component-names'] = 'off'; // 不允许使用箭头功能来定义观察者 (watch),原因是箭头函数绑定的this不是vue实例 v2v3['vue/no-arrow-functions-in-watch'] = 'error'; // 计算属性(computed)中禁止出现异步函数 , v2v3['vue/no-async-in-computed-properties'] = 'error'; // v-html和v-text不允许出现子元素 [
正确][
{{ aaa }}
错误] v2v3['vue/no-child-content'] = 'error'; // 在data中禁止访问计算属性(computed)因为data中computed的属性还没被生成 v2v3['vue/no-computed-properties-in-data'] = 'error'; // 禁止v-model自定义修饰器 v2['vue/no-custom-modifiers-on-v-model'] = 'error'; // 禁止在data上使用弃用的对象声明 v3['vue/no-deprecated-data-object-declaration'] = 'error'; // 禁止使用已经废弃的生命周期函数(vue3.0) v3['vue/no-deprecated-destroyed-lifecycle'] = 'error'; // 禁止使用 $listeners 因为 $listeners 已废弃 (vue3.0) v3['vue/no-deprecated-dollar-listeners-api'] = 'error'; // 禁止使用 .$scopedSlots 因为 .$scopedSlots 已废弃 (vue3.0) v3['vue/no-deprecated-dollar-scopedslots-api'] = 'error'; // 禁止使用 $on,$off,$once 因为 $on,$off,$once 已废弃 (vue3.0) v3['vue/no-deprecated-events-api'] = 'error'; // 禁止使用 {{ msg | filter }} filter已废弃 (vue3.0) v3['vue/no-deprecated-filter'] = 'error'; // 禁止使用