Eslint V9.x 在 Vue项目的配置参考及踩坑记录

〇. 概述

Eslint V9.x 对配置文件的结构进行了升级, 原先的配置已不再适用, 本文档旨在帮助你在项目中正确配置 ESLint V9.x

Ps: 可以使用Eslint提供的配置迁移工具将现有配置快速迁移至新版本:

npx @eslint/migrate-config .eslintrc.js

不过迁移过来的配置文件可能无法直接使用, 可以参考本文档进行修改

一. 安装相关依赖

以 vue + nuxt + prettier 项目为例

arduino 复制代码
npm install -D eslint eslint-config-prettier eslint-config-vue eslint-plugin-nuxt eslint-plugin-prettier eslint-plugin-vue @eslint/compat @babel/eslint-parser vue-eslint-parser globals

二. 添加格式代码命令

package.json:

json 复制代码
"scripts": {
    ...
    "lint:js": "eslint --fix"
}

Eslint V9.x 不支持--ext 等参数, 这些配置放到了eslint.config.mjs

三. 添加配置文件

Eslint V9.x 的配置文件不再使用 .eslintrc.js , 请使用 eslint.config.mjs

eslint.config.mjs:

基于使用 vant + vue3 + prettier 的项目配置, 可以根据项目实际情况进行调整

格式化忽略文件复用了.prettierignore, 当然也可以设置Eslint自己的忽略文件

js 复制代码
import babelParser from '@babel/eslint-parser'
import { includeIgnoreFile } from '@eslint/compat'
import { FlatCompat } from '@eslint/eslintrc'
import js from '@eslint/js'
import globals from 'globals'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import vueEslintParser from 'vue-eslint-parser'
​
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
  allConfig: js.configs.all
})
const prettierignorePath = path.resolve(__dirname, '.prettierignore') // 复用prettier的忽略文件
// 允许的非驼峰命名变量白名单
const camelcaseWhiteList = [
  'my_name',
]
// 自定义规则
const rules = {
  /*
    "off" or 0 - 关闭规则
    "warn" or 1 - 将规则视为一个警告(不会影响退出码)
    "error" or 2 - 将规则视为一个错误 (退出码为1) 
  */
  'vue/no-multiple-template-root': 'off', // template只允许有一个根标签, vue3不适用
  'vue/require-default-prop': 'off', // prop需要默认值
  'vue/require-prop-types': 'off', // prop需要指定类型
  'vue/multi-word-component-names': 'off', // vue组件名称命名规则
  'vue/no-v-model-argument': 'off',
  'vue/no-v-for-template-key': 'off', // vue3中template上可以使用key, 见文档: https://cn.vuejs.org/guide/essentials/list#maintaining-state-with-key
  'vue/no-v-html': 'off', // no-v-html存在XSS攻击风险
  'no-prototype-builtins': 'off',
  'no-new-func': 'off',
  'no-undef': 'warn',
  'no-undef-init': 'warn',
  'prefer-promise-reject-errors': 'off', // Promise被拒绝(rejected)的返回值是一个Error对象
  'no-case-declarations': 1, // switch无块级作用域, 所以不要在switch的case里用const/let, 或用{}将case包装成一个代码块
  // prettier相关规则
  'prettier/prettier': [
    'warn',
    {
      endOfLine: 'auto'
    }
  ],
  // === 而不是 ==
  eqeqeq: [
    1,
    'always',
    {
      null: 'ignore'
    }
  ],
  camelcase: [
    1,
    {
      properties: 'always',
      // 这里设置允许非驼峰的命名
      allow: camelcaseWhiteList
    }
  ],
  // 代码缩进
  indent: [
    1,
    2,
    {
      SwitchCase: 1,
      ignoredNodes: ['ConditionalExpression'],
      flatTernaryExpressions: false
    }
  ],
  // 定义未使用的校验
  'no-unused-vars': [
    1,
    {
      vars: 'all',
      args: 'none'
    }
  ],
  // 其他规则可自行添加
}
// 全局变量
const globalsConfig = {
  ...globals.node,
  ...globals.browser,
  $nuxt: 'readonly',
  wx: 'readonly',
  my: 'readonly',
  import: 'readonly'
  // 其他全局属性请添加到这里
}
export default [
  // 引入外部的忽略文件
  includeIgnoreFile(prettierignorePath),
  // 引入插件, 使用推荐的规则
  ...compat.extends('plugin:nuxt/recommended', 'plugin:vue/recommended', 'plugin:prettier/recommended'),
  {
    // 根据不同的文件类型分别配置, 因为需要不同的parser
    files: ['**/*.js', '*.js'],
    languageOptions: {
      globals: globalsConfig,
      parser: babelParser,
      ecmaVersion: 2024,
      sourceType: 'module',
      parserOptions: {
        parser: '@babel/eslint-parser',
        requireConfigFile: false,
        ecmaFeatures: {
          arrowFunctions: true,
          destructuring: true,
          classes: true,
          modules: true,
          experimentalObjectRestSpread: true,
          optionalChainingOperator: true
        }
      }
    },
    rules
  },
  {
    files: ['**/*.vue'],
    languageOptions: {
      globals: globalsConfig,
      parser: vueEslintParser,
      sourceType: 'module'
    },
    rules
  }
]

.prettierignore

ESLint支持引入外部忽略文件, 譬如 .gitignore 或者 .prettierignore

因为.prettierignore同样表示不需要参与代码格式化的文件/目录, 所以可以复用

此文件仅供参考, 请以项目实际情况调整配置, 或者可以使用其他的忽略文件

bash 复制代码
# 忽略的文件夹
public
style
node_modules
dist
​
# 忽略的文件
package-lock.json

对应上面eslint.config.mjs的部分代码

js 复制代码
import { includeIgnoreFile } from '@eslint/compat'
import path from 'node:path'
...
const __dirname = path.dirname(__filename)
const prettierignorePath = path.resolve(__dirname, '.prettierignore') // 复用prettier的忽略文件
export default [
  ...
  // 引入外部的忽略文件
  includeIgnoreFile(prettierignorePath),
  ...
]

四. 一些踩坑

1. 过时的编辑器配置

因为eslint更改了一些配置项, 所以可能存在报错的情况, 譬如提示:

bash 复制代码
- Unknow options: extensions
- 'extensions' has been removed

解决方法: 去VSCodesetting.json删除对应过时的配置

json 复制代码
"eslint.options": {
  "extensions": [".js", ".vue"]
}

2. 无法解析文件

不同格式的文件需要不同的parser解析, 请为不同的文件配置对应的parser

bash 复制代码
Parsing error: No Babel config file detected for ...

解决方法: 根据不同的文件类型分别配置不同的parser

js 复制代码
import babelParser from '@babel/eslint-parser'
import vueEslintParser from 'vue-eslint-parser'
​
export default [
  {
    // 根据不同的文件类型分别配置, 因为需要不同的parser
    // 为.js文件配置
    files: ['**/*.js', '*.js'],
    languageOptions: {
      ...
      parser: babelParser
    },
    ...
  },
  {
    // 为.vue文件配置
    files: ['**/*.vue'],
    languageOptions: {
      ...
      parser: vueEslintParser
    },
    ...
  }
    
]
相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
A黄俊辉A1 天前
uniapp webview中实现 app和内嵌的H5双向通信
vue.js·json
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
honkun61 天前
vue 表格组件 vxe-table 配置 ajax 请求自动加载数据与表单查询
vue.js·vxe-table
kybs19911 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端