vue项目配置Eslint + Prettier

797 阅读6分钟

根目录下.eslintrc.js

module.exports = {
    root: true, // 根目录标识,ESLint 一旦发现配置文件中有 "root": true,它就会停止在父级目录中寻找。
    env: {
        // 一个环境定义了一组预定义的全局变量
        browser: true,
        es2021: true,
        node: true
    },
    extends: [
        // 规则继承
        'plugin:vue/essential', // 引入eslint-plugin-vue插件,并开启essential类别中的一系列规则。vue 的额外添加的规则是 v-if, v-else 等指令检测
        /**
         * 有两种eslint规范,一种是自带了react插件的「eslint-config-airbnb」,一种是基础款「eslint-config-airbnb-base」,
         * 【】airbnb-base 包括了ES6的语法检测,需要依赖 「eslint-plugin-import」
         * 【】所以在使用airbnb-base时,需要用npm额外下载 eslint-plugin-import
         * 【】所以eslint实际上已经因为 airbnb-base 基础配置项目,添加上了 eslint-plugin-import 插件配置
         * 【】所以在setting和rules里,都有 'import/xxx' 项目,这里修改的就是 eslint-plugin-import 配置
         */
        'airbnb-base',
        'eslint:recommended', // 启用一系列核心规则,这些规则报告一些常见问题.这个推荐的子集只能在 ESLint 主要版本进行更新。
        '@vue/prettier' // 安装 @vue/eslint-config-prettier eslint-plugin-prettier
    ],
    parserOptions: {
        ecmaVersion: 12, // 默认设置为 3,5(默认), 你可以使用 6、7、8、9 或 10 来指定你想要使用的 ECMAScript 版本。你也可以用使用年份命名的版本号指定为 2015(同 6),2016(同 7),或 2017(同 8)或 2018(同 9)或 2019 (same as 10)
        // parser: '@typescript-eslint/parser', // 解析器, 默认为Espree,非ts建议写babel-eslint TODO(TS)
        parser: 'babel-eslint',
        sourceType: 'module' // 默认“script”
    },
    plugins: [
        'vue' // eslint-plugin-vue 帮助我们检测.vue文件中 <template> 和 <script> 中的js代码
        // '@typescript-eslint' // TODO(TS)
    ],
    rules: {
        'no-dupe-keys': 'error', // eslint:recommended: 禁止对象字面量中出现重复的 key
        'no-duplicate-case': 'warn', // eslint:recommended: 禁止出现重复的 case 标签
        'no-unreachable': 'warn', // eslint:recommended: 禁止在 return、throw、continue 和 break 语句之后出现不可达代码
        'no-unused-expressions': 'off', // Best Practices: 禁止出现未使用过的表达式
        'no-unused-vars': [
            // eslint:recommended: 禁止出现未使用过的变量
            'error',
            {
                // ts定义function,参数都会提示未使用,所以设置args
                ignoreRestSiblings: true, // 使用 Rest 属性 可能会“省略”对象中的属性,但是默认情况下,其兄弟属性被标记为 “unused”。使用该选项可以使 rest 属性的兄弟属性被忽略。
                args: 'none' // none - 不检查参数; all - 所有命名参数必须使用; after-used - 不检查最后一个使用的参数之前出现的未使用的位置参数,但是检查最后一个使用的参数之后的所有命名参数和所有位置参数。
            }
        ],
        'default-case': 'warn', // Best Practices: 要求 switch 语句中有 default 分支
        eqeqeq: 'warn', // Best Practices: 要求使用 === 和 !==
        'no-extra-label': 'warn', // Best Practices: 禁用不必要的标签
        'vue/no--unusedvars': 'off', // plugin:vue/essential有开启
        'vue/no-use-v-if-with-v-for': 'off', // plugin:vue/essential有开启
        // 'vue/no-multiple-template-root': 'off', // plugin:vue/essential有开启  TODO(VUE3可以使用)
        'prettier/prettier': [
            // 两者混合使用时候,需要修改规则,以防止重复或冲突;eslint-config-prettier 即为解决此问题的存在,可以使用它关闭所有可能引起冲突的规则。
            'off',
            {
                endOfLine: 'auto'
            }
        ],
        'import/extensions': [
            // import忽略后缀名
            'error',
            'always',
            {
                // ts: 'never',
                // tsx: 'never',
                js: 'never'
                // vue: 'never' // vue文件加后缀名才能跳转至定义处
            }
        ],
        'max-len': 'off', // 	Stylistic Issues: 强制一行的最大长度
        'prefer-destructuring': ['warn', { object: true, array: false }], // ECMAScript 6: 优先使用数组和对象解构
        'global-require': 'off', // Node.js and CommonJS: 要求 require() 出现在顶层模块作用域中
        'no-param-reassign': 'off', // Best Practices: 禁止对 function 的参数进行重新赋值
        'no-console': 'off', // 允许通过console调试,记得打包时将console相关的调试代码删掉
        'import/no-extraneous-dependencies': [
            // // Forbid the import of external modules that are not declared in the package.json's dependencies, devDependencies, optionalDependencies, peerDependencies, or bundledDependencies.
            'error',
            { devDependencies: true } // If set to false, then the rule will show an error when devDependencies are imported. Defaults to true.
        ],
        'vue/no-v-model-argument': 'off', // plugin:vue/essential有开启  This rule checks whether v-model used on custom component do not have an argumen
        'import/prefer-default-export': 'off',
        'no-alert': 'warn', // Best Practices: 禁用 alert、confirm 和 prompt
        'no-caller': 'warn', // Best Practices: 禁用 arguments.caller 或 arguments.callee
        'no-eq-null': 'warn', // Best Practices: 禁止在没有类型检查操作符的情况下与 null 进行比较
        'no-eval': 'warn', // Best Practices: 禁用 eval()
        'no-extend-native': 'warn', // Best Practices: 禁止扩展原生类型
        'no-var': 'warn', // ECMAScript 6: 要求使用 let 或 const 而不是 var
        'prefer-template': 'warn', // ECMAScript 6: 要求使用模板字面量而非字符串连接
        'consistent-return': 'off', // 要求 return 语句要么总是指定返回的值,要么不指定
        'no-plusplus': 'off', // i++
        'func-names': 'off'
    },
    settings: {
        // 规则共享参数 http://eslint.cn/docs/user-guide/configuring#adding-shared-settings
        // 'import/extensions': ['.js', '.jsx', '.ts', '.tsx'], // TODO(TS)
        // 'import/parsers': {
        //     '@typescript-eslint/parser': ['.ts', '.tsx'] // TODO(TS)
        // },
        // eslint识别webpack import别名
        'import/resolver': [
            // 安装eslint-import-resolver-webpack
            'node',
            {
                webpack: {
                    config: 'build/webpack.base.conf.js'
                }
            }
        ]
    }
    // globals: {
    //     // 当访问当前源文件内未定义的变量时,no-undef 规则将发出警告。如果你想在一个源文件里使用全局变量,推荐你在 ESLint 中定义这些全局变量。除了true还有值writable、readonly
    //     defineProps: true, // TODO(VUE3可以使用)
    //     defineEmits: true, // TODO(VUE3可以使用)
    //     defineExpose: true // TODO(VUE3可以使用)
    // }
};

根目录下.prettierrc.js

module.exports = {
    printWidth: 100, // 单行长度
    tabWidth: 4, // 缩进长度
    useTabs: false, // 使用空格代替tab缩进
    semi: true, // 句末使用分号
    singleQuote: true, // 使用单引号
    bracketSpacing: true, // 在对象前后添加空格-eg: { foo: bar }
    jsxBracketSameLine: true, // 多属性html标签的‘>’折行放置
    endOfLine: 'lf', // 结束行形式
    trailingComma: 'none',
};

安装eslint相关包;添加eslint检查命令;配置git commit之前检查eslint

package.json

{
  "scripts": {
    "lint": "eslint --color --ext .js,.vue src",
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "src/**/*.{js,vue}": [
      "eslint --color"
    ]
  },
  "devDependencies": {
    "@vue/eslint-config-prettier": "^7.0.0",
    "eslint": "^7.32.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-import-resolver-webpack": "^0.13.2",
    "eslint-plugin-import": "^2.25.4",
    "eslint-plugin-vue": "^7.20.0",
  },
}

vscode配置eslint检查

settings.json

{
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true 
    },
    "eslint.alwaysShowStatus": true,
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "html",
        "vue"
    ]
}

import无法跳转有webpack别名的路径

jsconfig.json

{
    "compilerOptions": {
        "target": "esnext",
        "module": "esnext",
        "sourceMap": true,
        "allowJs": true,
        "moduleResolution": "node",
        "baseUrl": ".",
        "paths": {
            "@src/*": ["src/*"]
        },
    },
    "include": [
        "src/**/*.js",
        "src/**/*.vue",
    ],
    "exclude": [
        "node_modules",
        "dist"
    ]
}

ts则配置tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "sourceMap": true,
    "allowJs": true,
    "moduleResolution": "node",
    "checkJs": true,
    "allowSyntheticDefaultImports": true,
    "strict": true, // 这样可以对`this`上的数据属性进行严格的推断,否则总是被视为any类型
    "jsx": "preserve",
    "noImplicitAny": true, // 使用隐含any类型引发表达式和声明错误。如果参数const, let, 或var没有类型,这将引发错误。
    "noImplicitThis": true,
    "noImplicitReturns": true, // 函数中并非所有代码路径都返回值时报错。这有助于确保具有返回类型的给定函数中的所有条件都返回一个值。
    "importHelpers": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ],
  "exclude": [
      "node_modules",
  ]
}

注意:vscode引入的项目根目录必须是当前项目,否则import点击跳转、智能提示都有问题

遇到的问题

  • vscode保存时会自动将函数参数尾部的逗号去掉,导致eslint报错。 因为eslint配置了:
'comma-dangle': ['error', 'always-multiline'],

prettier有配置

trailingComma: 'es5',

最后找到的解决方案是:

  1. 右键选择:“使用...格式化文档”
  2. 点击:“配置默认格式化程序...”
  3. 选择:“Prettier Eslint”