常用的eslint规则
示例使用了 eslint@9。
.prettierrc
搭配 prettier 配置使用
json
{
"singleQuote": true,
"trailingComma": "none",
"semi": true,
"printWidth": 120,
"proseWrap": "never",
"endOfLine": "auto"
}
Typescript通用
不和框架相关,适合ts基础项目
安装命令
shell
yarn add -D \
eslint \
@eslint/js \
prettier \
eslint-plugin-prettier \
eslint-plugin-import \
eslint-config-prettier \
typescript \
typescript-eslint \
@typescript-eslint/eslint-plugin \
@typescript-eslint/parser \
eslint-import-resolver-typescript
eslint.config.mjs
js
import eslint from '@eslint/js';
import { defineConfig } from 'eslint/config';
import importPlugin from 'eslint-plugin-import';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import globals from 'globals';
import tseslint from 'typescript-eslint';
export default defineConfig([
{
ignores: ['']
},
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
eslintPluginPrettierRecommended,
{
plugins: {
import: importPlugin
},
languageOptions: {
globals: {
...globals.node,
...globals.browser
},
sourceType: 'module',
parserOptions: {
projectService: true,
}
},
settings: {
'import/resolver': {
typescript: {} // 使用 tsconfig.json 中的 paths 字段
}
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
// 不强制所有函数必须显式声明返回类型
'@typescript-eslint/explicit-function-return-type': 'off',
// 不要求所有模块公有导出(函数、方法)必须显式声明参数与返回类型
'@typescript-eslint/explicit-module-boundary-types': 'off',
// 关闭“对 any 类型变量赋值”的限制(例如:const a: any = ...)
// 在某些快速开发场景中可容忍此类不安全赋值
'@typescript-eslint/no-unsafe-assignment': 'off',
// 关闭“对 any 类型成员访问”的限制(例如:a.b.c)
// 适用于对第三方库、全局变量等非类型安全场景的宽松处理
'@typescript-eslint/no-unsafe-member-access': 'off',
// 关闭“对 any 类型函数调用”的限制(例如:anyFunc())
// 可减少类型不完整时的报错干扰,但需自行保证调用安全性
'@typescript-eslint/no-unsafe-call': 'off',
// 关闭“未绑定方法直接赋值”的限制(例如:const fn = obj.method)
// 在某些 class 实例或函数绑定场景下更方便使用
'@typescript-eslint/unbound-method': 'off',
// import 顺序规则
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', ['parent', 'sibling', 'index']],
pathGroups: [
{
pattern: '@/**',
group: 'internal',
position: 'after'
}
],
pathGroupsExcludedImportTypes: ['builtin'],
'newlines-between': 'ignore',
alphabetize: {
order: 'asc',
caseInsensitive: true
}
}
]
}
}
]);
Vue+Typescript
安装命令
shell
yarn add -D \
eslint @eslint/js \
typescript typescript-eslint \
@typescript-eslint/eslint-plugin @typescript-eslint/parser @typescript-eslint/utils \
prettier eslint-plugin-prettier eslint-config-prettier \
eslint-plugin-import eslint-import-resolver-typescript \
eslint-plugin-vue vue-eslint-parser jiti
eslint.config.mjs
mjs
import js from '@eslint/js';
import parserTs from '@typescript-eslint/parser';
import { defineConfig } from 'eslint/config';
import importPlugin from 'eslint-plugin-import';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import pluginVue from 'eslint-plugin-vue';
import globals from 'globals';
import tseslint from 'typescript-eslint';
import vueParser from 'vue-eslint-parser';
export default defineConfig([
// 忽略文件
{
ignores: []
},
js.configs.recommended,
// TypeScript 推荐规则(开启类型检查)
...tseslint.configs.recommendedTypeChecked,
...pluginVue.configs['flat/recommended'],
eslintPluginPrettierRecommended,
{
files: ['**/*.{ts,tsx,vue,js,mjs,cjs}'],
plugins: {
import: importPlugin
},
languageOptions: {
// Vue 文件主解析器
parser: vueParser,
globals: {
...globals.node,
...globals.browser
},
parserOptions: {
// 用于 <script lang="ts"> 的嵌套解析器
parser: parserTs,
extraFileExtensions: ['.vue'],
projectService: true // 需要 typescript-eslint >= 7.0
}
},
settings: {
'import/resolver': {
typescript: {} // 支持 tsconfig.json 中的 paths
}
},
rules: {
/* ===== TypeScript ===== */
'@typescript-eslint/no-explicit-any': 'off',
// 不强制所有函数必须显式声明返回类型
'@typescript-eslint/explicit-function-return-type': 'off',
// 不要求所有模块公有导出(函数、方法)必须显式声明参数与返回类型
'@typescript-eslint/explicit-module-boundary-types': 'off',
// 关闭“对 any 类型变量赋值”的限制(例如:const a: any = ...)
// 在某些快速开发场景中可容忍此类不安全赋值
'@typescript-eslint/no-unsafe-assignment': 'off',
// 关闭“对 any 类型成员访问”的限制(例如:a.b.c)
// 适用于对第三方库、全局变量等非类型安全场景的宽松处理
'@typescript-eslint/no-unsafe-member-access': 'off',
// 关闭“对 any 类型函数调用”的限制(例如:anyFunc())
// 可减少类型不完整时的报错干扰,但需自行保证调用安全性
'@typescript-eslint/no-unsafe-call': 'off',
// 关闭“未绑定方法直接赋值”的限制(例如:const fn = obj.method)
// 在某些 class 实例或函数绑定场景下更方便使用
'@typescript-eslint/unbound-method': 'off',
/* ===== Vue ===== */
// 标签内容不强制换行,与 prettier 冲突
'vue/singleline-html-element-content-newline': 'off',
'vue/multiline-html-element-content-newline': 'off',
// 自闭合标签风格与 prettier 冲突
'vue/html-self-closing': 'off',
// 允许使用 v-html
'vue/no-v-html': 'off',
// 属性强制使用 camelCase
'vue/attribute-hyphenation': [
'error',
'never',
{
ignore: [
'accept-charset',
'http-equiv',
'accesskey',
'contenteditable',
'tabindex',
'maxlength',
'minlength',
'autocomplete',
'autocapitalize',
'spellcheck',
'crossorigin',
'referrerpolicy',
'aria-*',
'data-*'
]
}
],
// 强制事件名使用 camelCase
'vue/v-on-event-hyphenation': [
'error',
'never',
{
autofix: true,
ignore: []
}
],
// 强制组件名使用 PascalCase
'vue/component-name-in-template-casing': [
'error',
'PascalCase',
{
registeredComponentsOnly: false,
ignores: []
}
],
// 每行最多 4 个属性(根据你的设置关闭强制)
'vue/max-attributes-per-line': ['off'],
/* ===== Import 顺序 ===== */
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', ['parent', 'sibling', 'index']],
pathGroups: [
{
pattern: '@/**',
group: 'internal',
position: 'after'
}
],
pathGroupsExcludedImportTypes: ['builtin'],
'newlines-between': 'ignore',
alphabetize: {
order: 'asc',
caseInsensitive: true
}
}
]
}
}
]);
React+Typescript
安装命令
shell
yarn add -D \
eslint \
@eslint/js \
prettier \
eslint-plugin-prettier \
eslint-plugin-import \
eslint-config-prettier \
eslint-plugin-react-hooks \
eslint-plugin-react-refresh \
typescript \
typescript-eslint \
@typescript-eslint/eslint-plugin \
@typescript-eslint/parser \
eslint-import-resolver-typescript
eslint.config.mjs
js
import eslint from '@eslint/js';
import { defineConfig } from 'eslint/config';
import importPlugin from 'eslint-plugin-import';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import globals from 'globals';
import tseslint from 'typescript-eslint';
export default defineConfig([
{
ignores: ['lib', 'eslint.config.mjs']
},
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
eslintPluginPrettierRecommended,
{
plugins: {
import: importPlugin,
'react-hooks': reactHooks,
'react-refresh': reactRefresh
},
languageOptions: {
globals: {
...globals.node,
...globals.browser
},
sourceType: 'module',
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname
}
},
settings: {
'import/resolver': {
typescript: {} // 使用 tsconfig.json 中的 paths 字段
}
},
rules: {
...reactHooks.configs.recommended.rules,
'@typescript-eslint/no-explicit-any': 'off',
// 不强制所有函数必须显式声明返回类型
'@typescript-eslint/explicit-function-return-type': 'off',
// 不要求所有模块公有导出(函数、方法)必须显式声明参数与返回类型
'@typescript-eslint/explicit-module-boundary-types': 'off',
// 关闭“对 any 类型变量赋值”的限制(例如:const a: any = ...)
// 在某些快速开发场景中可容忍此类不安全赋值
'@typescript-eslint/no-unsafe-assignment': 'off',
// 关闭“对 any 类型成员访问”的限制(例如:a.b.c)
// 适用于对第三方库、全局变量等非类型安全场景的宽松处理
'@typescript-eslint/no-unsafe-member-access': 'off',
// 关闭“对 any 类型函数返回值”的限制(例如:function foo(): any { ... })
'@typescript-eslint/no-unsafe-return': 'off',
// 关闭“对 any 类型函数调用”的限制(例如:anyFunc())
// 可减少类型不完整时的报错干扰,但需自行保证调用安全性
'@typescript-eslint/no-unsafe-call': 'off',
// 关闭“未绑定方法直接赋值”的限制(例如:const fn = obj.method)
// 在某些 class 实例或函数绑定场景下更方便使用
'@typescript-eslint/unbound-method': 'off',
// import 顺序规则
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', ['parent', 'sibling', 'index']],
pathGroups: [
{
pattern: '@/**',
group: 'internal',
position: 'after'
}
],
pathGroupsExcludedImportTypes: ['builtin'],
'newlines-between': 'ignore',
alphabetize: {
order: 'asc',
caseInsensitive: true
}
}
]
}
}
]);
注意
eslint.config.mjs was not found by the project service
text
eslint.config.mjs was not found by the project service. Consider either including it in the tsconfig.json
出现类似的情况,将 eslint.config.mjs 写到 tsconfig.json 的 node 设定中。并且设置 "allowJs": true。
![[微笑]](/face/0.gif)
![[嘻嘻]](/face/1.gif)
![[哈哈]](/face/2.gif)
![[可爱]](/face/3.gif)
![[可怜]](/face/4.gif)
![[挖鼻]](/face/5.gif)
![[吃惊]](/face/6.gif)
![[害羞]](/face/7.gif)
![[挤眼]](/face/8.gif)
![[闭嘴]](/face/9.gif)
![[鄙视]](/face/10.gif)
![[爱你]](/face/11.gif)
![[泪]](/face/12.gif)
![[偷笑]](/face/13.gif)
![[亲亲]](/face/14.gif)
![[生病]](/face/15.gif)
![[太开心]](/face/16.gif)
![[白眼]](/face/17.gif)
![[右哼哼]](/face/18.gif)
![[左哼哼]](/face/19.gif)
![[嘘]](/face/20.gif)
![[衰]](/face/21.gif)
![[委屈]](/face/22.gif)
![[吐]](/face/23.gif)
![[哈欠]](/face/24.gif)
![[抱抱]](/face/25.gif)
![[怒]](/face/26.gif)
![[疑问]](/face/27.gif)
![[馋嘴]](/face/28.gif)
![[拜拜]](/face/29.gif)
![[思考]](/face/30.gif)
![[汗]](/face/31.gif)
![[困]](/face/32.gif)
![[睡]](/face/33.gif)
![[钱]](/face/34.gif)
![[失望]](/face/35.gif)
![[酷]](/face/36.gif)
![[色]](/face/37.gif)
![[哼]](/face/38.gif)
![[鼓掌]](/face/39.gif)
![[晕]](/face/40.gif)
![[悲伤]](/face/41.gif)
![[抓狂]](/face/42.gif)
![[黑线]](/face/43.gif)
![[阴险]](/face/44.gif)
![[怒骂]](/face/45.gif)
![[互粉]](/face/46.gif)
![[心]](/face/47.gif)
![[伤心]](/face/48.gif)
![[猪头]](/face/49.gif)
![[熊猫]](/face/50.gif)
![[兔子]](/face/51.gif)
![[ok]](/face/52.gif)
![[耶]](/face/53.gif)
![[good]](/face/54.gif)
![[NO]](/face/55.gif)
![[赞]](/face/56.gif)
![[来]](/face/57.gif)
![[弱]](/face/58.gif)
![[草泥马]](/face/59.gif)
![[神马]](/face/60.gif)
![[囧]](/face/61.gif)
![[浮云]](/face/62.gif)
![[给力]](/face/63.gif)
![[围观]](/face/64.gif)
![[威武]](/face/65.gif)
![[奥特曼]](/face/66.gif)
![[礼物]](/face/67.gif)
![[钟]](/face/68.gif)
![[话筒]](/face/69.gif)
![[蜡烛]](/face/70.gif)
![[蛋糕]](/face/71.gif)