【问题标题】:How to configure Vue CLI 4 with ESLint + Airbnb rules + TypeScript + Stylelint for SCSS, in VS Code editor with autofix on save?如何在 VS Code 编辑器中使用 ESLint + Airbnb 规则 + TypeScript + Stylelint 为 SCSS 配置 Vue CLI 4,并在保存时自动修复?
【发布时间】:2020-05-27 23:37:01
【问题描述】:

注意:这是一个与我之前关于该主题的问题类似的问题,该问题部分未解决,之后挑战的性质发生了很大变化:How to configure Vue CLI 4 with ESLint + Prettier + Airbnb rules + TypeScript + Vetur?

在 2019 年,我非常着迷于使用 TypeScript 中的 Vue 配置“圣杯”工具设置,并让 VS Code 自动修复您保存在 .vue、.ts 文件中的代码, 和 .scss 文件。

但是让Prettier 与ESLint 和Vetur 以最佳方式工作最终是一个太大的挑战。由于 Prettier 和 ESLint 的内在冲突具有部分相同的目标和相似的规则检查,并且 Vetur 为 VS Code 中的这种特殊组合增加了更多复杂性。

此外,当设置大部分工作时,您需要连续多次保存文件是相当烦人的。因为一旦 ESLint 发现并修复了一组错误,就会出现新的错误,而且它还不够先进,无法连续运行这些检查和修复,直到所有错误都被清除...

2019 年 11 月,我参加了 Vue Conf Toronto,在 Evan 先生的研讨会 Deep Dive with Vue 3.0 中,我向他询问了这个问题。他说官方工具很快就会进行大修,新版本的 ESLint 将会有新的功能......

他还暗示,此时几乎所有 Vue 官方 Style Guide 的规则检查都写入了自动修复逻辑,结合即将推出的 Vue 3.0 完全模块化架构,甚至可能会看到官方的 VS Code 扩展。或者至少通过利用这些新功能让 Vetur 和类似插件更容易运行代码检查和修复。

2019 年 12 月,Vue CLI 4.1 插件和预设升级带来了 ESLint 版本 6 功能。这意味着我们可以开始将 ESLint 不仅用作 linter,还可以用作格式化程序,从而有效地在我们的设置中消除对 Prettier 的需求。

同时,ESLint 发布了其官方 VS Code 扩展 dbaeumer.vscode-eslint 的第 2 版,引入了对 VS Code 的 Run Code Actions on save -feature 的支持,由 editor.codeActionsOnSave -setting 控制。

因此,最终清除了运行此设置的路径! 接下来,我将回答我自己关于如何配置此组合的问题。

PS。虽然 Vetur 可能仍可用作此设置的一部分,但在这里我已更改为使用 Stylelint。 Stylelint 的自动修复功能仍然存在一些问题,但可能会通过未来的更新来解决。 但我仍然有兴趣了解 Vetur 在有或没有 Stylelint 的情况下是否有用!

【问题讨论】:

    标签: javascript typescript vue.js eslint vue-cli


    【解决方案1】:

    官方脚手架 Vue CLI 项目的配置

    在 2020 年 2 月在创建项目脚手架中升级 Vue CLI 4.2 之后,通过使用全局 vue create myproject 命令创建一个新项目并至少进行这些选择(包括的配置),您已完成配置的一半下面):

    Vue CLI v4.2.2
    ? Please pick a preset: Manually select features
    ? Check the features needed for your project:
     (*) Babel
     (*) TypeScript
     ( ) Progressive Web App (PWA) Support
     ( ) Router
     ( ) Vuex
     (*) CSS Pre-processors
    >(*) Linter / Formatter
     ( ) Unit Testing
     ( ) E2E Testing     
    
    ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n) Y 
    
    ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default):
      Sass/SCSS (with dart-sass)
    > Sass/SCSS (with node-sass)
      Less
      Stylus      
    
    ? Pick a linter / formatter config:
      ESLint with error prevention only
    > ESLint + Airbnb config
      ESLint + Standard config
      ESLint + Prettier
      TSLint (deprecated)    
    
    ? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
    >(*) Lint on save
     ( ) Lint and fix on commit 
    
    ? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
    > In dedicated config files
      In package.json                                                                                                                             
    

    现在您可能想知道为什么我选择node-sass 而不是第一个建议选项dart-sass - 原因如下:Vue CLI CSS pre-processor option: dart-sass VS node-sass?

    在package.json 中,您至少获得了这些依赖项:

      "dependencies": {
        "core-js": "^3.6.4",
        "vue": "^2.6.11"
      },
      "devDependencies": {
        "@typescript-eslint/eslint-plugin": "^2.18.0",
        "@typescript-eslint/parser": "^2.18.0",
        "@vue/cli-plugin-babel": "~4.2.0",
        "@vue/cli-plugin-eslint": "~4.2.0",
        "@vue/cli-plugin-typescript": "~4.2.0",
        "@vue/cli-service": "~4.2.0",
        "@vue/eslint-config-airbnb": "^5.0.2",
        "@vue/eslint-config-typescript": "^5.0.1",
        "eslint": "^6.7.2",
        "eslint-plugin-import": "^2.20.1",
        "eslint-plugin-vue": "^6.1.2",
        "node-sass": "^4.12.0",
        "sass-loader": "^8.0.2",
        "typescript": "~3.7.5",
        "vue-template-compiler": "^2.6.11"
      }
    

    .eslintrc.js:

    module.exports = {
      root: true,
      env: {
        node: true,
      },
      extends: [
        'plugin:vue/essential',
        '@vue/airbnb',
        '@vue/typescript/recommended',
      ],
      parserOptions: {
        ecmaVersion: 2020,
      },
      rules: {
        'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
      },
    };
    

    与.editorconfig:

    [*.{js,jsx,ts,tsx,vue}]
    indent_style = space
    indent_size = 2
    end_of_line = lf
    trim_trailing_whitespace = true
    insert_final_newline = true
    max_line_length = 100
    

    用于 linting 和格式化的有偏见的配置更改

    因此,我对.eslintrc.js 进行了偏颇的修改:

    module.exports = {
      root: true,
      env: {
        node: true,
      },
      extends: [
        'plugin:vue/recommended',
        '@vue/airbnb',
        '@vue/typescript/recommended',
      ],
      parserOptions: {
        ecmaVersion: 2020,
      },
      rules: {
        'class-methods-use-this': 0,
        // Changing max row length from 80 to 150.
        // Remember to change in .editorconfig also, although am not sure if that file is even needed?
        // Especially as scaffolding gave 100 as max len while ESLint default is 80...
        'max-len': [
          'error',
          {
            code: 150,
            ignoreComments: true,
            ignoreUrls: true,
          },
        ],
        'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
        '@typescript-eslint/ban-ts-ignore': 0,
      },
      // These are added if you chose also to install Jest plugin for Vue CLI
      // With my own modifications here as an example
      overrides: [
        {
          files: [
            './src/**/__tests__/*.spec.{j,t}s',
            './src/**/__mock__/*.{j,t}s',
          ],
          env: {
            jest: true,
          },
          rules: {
            'no-unused-expressions': 0,
          },
        },
      ],
    };
    

    然后我添加了.eslintignore 文件:

    # Lint config files in the root ending .js
    !/*.js
    

    然后我在.editorconfig 顶部添加了这个部分(虽然不确定是否需要这个文件):

    # EditorConfig is awesome: https://EditorConfig.org
    
    # top-most EditorConfig file
    root = true
    

    安装和配置 Stylelint

    Stylelint 是一个类似于 CSS/SCSS/SASS/LESS/Stylus 的项目,而不是用于 JavaScript/TypeScript 的 ESLint,同样可以通过插件和预设进行扩展。它有一个官方的 VS Code 扩展,也可以在你的 Webpack 构建过程中运行。

    我选择使用 stylelint-scss package 扩展 Stylelint,目前每周有 50 万次下载,stylelint-config-recommended-scss package 来自同一维护者。此外,我已将 stylelint-webpack-plugin 配置为 Webpack 构建过程的一部分。

    通过以下方式从命令行安装这些开发依赖项:npm i -D stylelint stylelint-config-recommended-scss stylelint-scss stylelint-webpack-plugin

    添加一个文件.stylelintrc.json,并以一些有偏见的规则修改为例(可能需要Vue的::v-deep自定义选择器处理):

    {
      "extends": "stylelint-config-recommended-scss",
      "rules": {
        "max-nesting-depth": 4,
        "no-descending-specificity": null,
        "property-no-unknown": [
          true,
          {
            "ignoreProperties": ["user-drag", "font-smooth"]
          }
        ],
        "selector-pseudo-element-no-unknown": [
          true,
          {
            "ignorePseudoElements": ["v-deep"]
          }
        ]
      }
    }
    

    创建文件或添加到vue.config.js,这是一些有偏见的配置示例:

    // Add in the top of the file
    const StyleLintPlugin = require('stylelint-webpack-plugin');
    
    module.exports = {
      css: {
        loaderOptions: {
          sass: {
            // Here as example if needed:
            // Import Sass vars and mixins for SFC's style blocks
            prependData: '@import "@/assets/styles/abstracts/_variables.scss"; @import "@/assets/styles/abstracts/_mixins.scss";',
          },
        },
      },
      lintOnSave: process.env.NODE_ENV !== 'production',
      productionSourceMap: false,
      devServer: {
        overlay: {
          warnings: true,
          errors: true,
        },
      },
      configureWebpack: {
        // Fast source maps in dev
        devtool: process.env.NODE_ENV === 'production' ? false : 'cheap-eval-source-map',
        plugins: [
          new StyleLintPlugin({
            files: 'src/**/*.{vue,scss}',
          }),
        ],
        resolve: {
          alias: {
            // Alias @ to /src folder for ES/TS imports
            '@': path.join(__dirname, '/src'),
          },
        },
      },
    };
    

    VS Code 编辑器、扩展和设置

    在项目根目录中创建 .vscode 命名文件夹,用于放置项目特定设置和扩展建议。请注意,如果您在工作区模式下打开 VS Code(一次包含多个项目根目录),某些设置在此模式下不起作用,所以我总是直接打开项目根目录而不使用工作区模式。

    在这个文件夹中添加一个文件extensions.json,至少推荐这个内容,然后安装扩展。

    {
      "recommendations": [
        // ESLint - Integrates ESLint JavaScript into VS Code.
        "dbaeumer.vscode-eslint",
        // Disable eslint rule - Disable eslint rule with one click.
        "wooodhead.disable-eslint-rule",
        // eslint-disable-snippets - Simple snippets for disable eslint rules
        "drknoxy.eslint-disable-snippets",
        // Vue - Syntax highlight for Vue.js
        "jcbuisson.vue",
        // stylelint - Modern CSS/SCSS/Less linter
        "stylelint.vscode-stylelint",
        // EditorConfig for VS Code - EditorConfig Support for Visual Studio Code
        // Not sure if this is needed or recommended,
        // but .editorconfig file is still included in the scaffolded project...
        "editorconfig.editorconfig",
        // DotENV - Support for dotenv file syntax.
        "mikestead.dotenv",
      ]
    }
    

    使用这些或类似设置添加另一个文件settings.json:

    {
      // EDITOR
      // ----------------------------------------
      "editor.defaultFormatter": "dbaeumer.vscode-eslint",
      "[javascript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" },
      "[typescript]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" },
      "[vue]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" },
      "[scss]": { "editor.defaultFormatter": "stylelint.vscode-stylelint" },
      "[css]": { "editor.defaultFormatter": "stylelint.vscode-stylelint" },
      "editor.codeActionsOnSave": {
        // https://github.com/microsoft/vscode-eslint/blob/master/README.md#release-notes
        "source.fixAll.eslint": true,
        "source.fixAll.stylelint": true
      },
    
      // ESLINT
      // ----------------------------------------
      "eslint.enable": true,
      "eslint.alwaysShowStatus": true,
      "eslint.options": {
        "extensions": [".html", ".js", ".ts", ".vue"]
      },
    
      // VETUR
      // Disable rules if user has extension installed and enabled.
      // ----------------------------------------
      "vetur.validation.template": false,
      "vetur.validation.style": false,
      "vetur.format.defaultFormatter.html": "none",
      "vetur.format.defaultFormatter.css": "none",
      "vetur.format.defaultFormatter.scss": "none",
      "vetur.format.defaultFormatter.js": "none",
      "vetur.format.defaultFormatter.ts": "none",
    
      // STYLELINT
      // ----------------------------------------
      "stylelint.enable": true,
      "css.validate": true,
      "scss.validate": true,
    
      // HTML
      // ----------------------------------------
      "html.format.enable": false,
      "emmet.triggerExpansionOnTab": true,
      "emmet.includeLanguages": {
        "vue-html": "html"
      },
    
      // FILES
      // ----------------------------------------
      "files.exclude": {
        "**/*.log": true,
        "**/*.log*": true,
        "**/dist": true,
      },
      "files.associations": {
        ".babelrc": "jsonc",
        ".eslintrc": "jsonc",
        ".markdownlintrc": "jsonc",
        "*.config.js": "javascript",
        "*.spec.js": "javascript",
        "*.vue": "vue"
      },
      // The default end of line character. Use \n for LF and \r\n for CRLF.
      "files.eol": "\n",
      "files.insertFinalNewline": true,
      "files.trimFinalNewlines": true,
      "files.trimTrailingWhitespace": true,
    }
    

    所以这些是我有偏见的项目设置,我有兴趣听取改进建议!

    【讨论】:

    • 感谢分享!它没有让我自动格式化独立的.ts 文件。我必须按照此处的建议将"eslint.validate": ["typescript"], 添加到settings.json:github.com/microsoft/vscode-eslint/issues/864。这似乎是 eslint 中的一个错误。 编辑:删除了我之前关于 html 格式无效的评论(它确实有效)。
    • @ux.engineer 你只使用 Typescript 文件,你使用 Vue 单文件组件吗?如果您使用 Vue 单文件组件,请告诉我您是否也使用 Typescript。我的问题是 eslint 在我的
    • 您的解决方案在我的 Vue CLI 项目中非常适合我。格式化似乎有效,但奇怪的是 VS Code 一直显示Extension 'ESlint' cannot format 'src/App.vue'(具有不同的文件名 ofc。)知道发生了什么吗?
    • @MichalLevý 不确定那里有什么问题。在接下来的几周内,我将在一些帮助下对这种 linting 和格式化设置进行可能的改进。也将在这里更新更改。我也很想知道社区中的其他人是否有改进建议!
    • 对于任何无法在单个文件 Vue 组件中格式化 HTML 的人,我错过了一个可能是关键的细节:注意默认 .eslintrc.js 和带有 @ux.engineer 的“偏见”版本之间的区别" 更改 - `plugin:vue/essential => plugin:vue/recommended。这对我有用,您可以在此处查看具体规则 - eslint.vuejs.org/rules
    猜你喜欢
    • 2020-02-28
    • 2019-03-08
    • 2020-09-09
    • 2020-11-03
    • 2019-11-10
    • 2017-03-24
    • 2021-01-02
    • 1970-01-01
    • 2021-07-13
    相关资源
    最近更新 更多