简体   繁体   English

如何在 VS Code 编辑器中使用 ESLint + Airbnb 规则 + TypeScript + Stylelint 为 SCSS 配置 Vue CLI 4,并在保存时自动修复?

[英]How to configure Vue CLI 4 with ESLint + Airbnb rules + TypeScript + Stylelint for SCSS, in VS Code editor with autofix on save?

Note: This is a similar question to my previous question on the topic, which was left partly unsolved and after which the nature of the challenge changed considerably : How to configure Vue CLI 4 with ESLint + Prettier + Airbnb rules + TypeScript + Vetur?注意:这与我之前关于该主题的问题类似,该问题部分未解决,之后挑战的性质发生了很大变化如何使用 ESLint + Prettier + Airbnb 规则 + TypeScript + Vetur 配置 Vue CLI 4?

In 2019 I was fairly obsessed by getting a 'holy grail' tooling setup configured with Vue in TypeScript and having VS Code to autofix your code on file save in .vue, .ts, and .scss files .在 2019 年,我非常着迷于在 TypeScript 中使用 Vue配置“圣杯”工具设置,并让VS Code 自动修复保存在 .vue、.ts 和 .scss 文件中的文件中的代码

But getting Prettier to work optimally with ESLint and Vetur ended up being too much of a challenge.但是让PrettierESLintVetur进行最佳合作最终是一个太大的挑战。 Because of an inherent clash with Prettier and ESLint having partly the same aim and similar rule checks, and with Vetur adding more complexity to this particular mix in VS Code.因为 Prettier 和 ESLint 的内在冲突具有部分相同的目标和相似的规则检查,并且 Vetur 为 VS Code 中的这种特殊组合增加了更多的复杂性。

Also when the setup was mostly working, it was rather irritating that you needed to save the file several times in a row.此外,当设置大部分工作时,您需要连续多次保存文件是相当烦人的。 Because once ESLint found and fixed a set of errors, new errors appeared and it was not advanced enough to run those checks and fixes in a row until all was cleared...因为一旦 ESLint 发现并修复了一组错误,就会出现新的错误,并且它还不够先进,无法连续运行这些检查和修复,直到所有错误都被清除......

In November 2019 I was attending Vue Conf Toronto, and in Mr. Evan's workshop Deep Dive with Vue 3.0 I got to ask him about this problem. 2019 年 11 月,我参加了 Vue Conf Toronto,在 Evan 先生的研讨会 Deep Dive with Vue 3.0 中,我向他询问了这个问题。 He told that the official tooling is going to see major overhauling pretty soon, and there will be new features coming in from newer versions of ESLint...他说官方工具很快就会看到大修,并且新版本的 ESLint 将会有新功能......

He also hinted that at this point there is autofix logic written to nearly all of Vue's official Style Guide 's rule checks, which in combination with the upcoming Vue 3.0 fully modular architecture may even see an official VS Code extension coming.他还暗示,在这一点上,几乎所有 Vue 官方Style Guide的规则检查都写入了自动修复逻辑,结合即将推出的 Vue 3.0 完全模块化架构,甚至可能会看到官方的 VS Code 扩展。 Or at least is making it easier for Vetur and similar plugins to run code checks and fixes by leveraging these new capabilities.或者至少通过利用这些新功能,让 Vetur 和类似插件更容易运行代码检查和修复。

In December 2019, Vue CLI 4.1 plugins and presets upgrades brought ESLint version 6 features on the table. 2019 年 12 月, Vue CLI 4.1 插件和预设升级带来了 ESLint 版本 6 的功能 Which meant we could start using ESLint not just as a linter, but also a formatter , effectively dropping the need for Prettier in our setups.这意味着我们不仅可以开始使用ESLint 作为 linter,还可以作为 formatter ,从而有效地在我们的设置中消除对 Prettier的需求

During the same time ESLint released version 2 of it's official VS Code extension dbaeumer.vscode-eslint , bringing in support for VS Code's Run Code Actions on save -feature, controlled by editor.codeActionsOnSave -setting.与此同时,ESLint 发布了其官方 VS Code 扩展dbaeumer.vscode-eslint的第 2 版,引入了对 VS Code 的Run Code Actions on save功能的支持,由editor.codeActionsOnSave设置控制。

So finally the path was cleared for getting this setup running!因此,最终清除了运行此设置的路径! Next up, I'll answer my own question on how to configure this mix.接下来,我将回答我自己关于如何配置此组合的问题。

PS. PS。 While it's possible Vetur could still be used as a part of this setup, here I've changed to using Stylelint.虽然 Vetur 可能仍可用作此设置的一部分,但在这里我已更改为使用 Stylelint。 There has still been some problems with Stylelint's autofix feature, but is likely to be solved by future updates. Stylelint 的自动修复功能仍然存在一些问题,但可能会通过未来的更新来解决。 Yet I'm still interested in hearing if Vetur would prove useful with or without Stylelint!然而,我仍然有兴趣了解 Vetur 在有无 Stylelint 的情况下是否有用!

Official scaffolded Vue CLI project's configurations官方脚手架 Vue CLI 项目的配置

After Vue CLI 4.2 upgrades in create project scaffolding in February 2020 , you are half way through the configurations by creating a new project with global vue create myproject command and making at least these selections (configurations included below):在 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                                                                                                                             

Now you may be wondering why I chose node-sass over the first suggested option dart-sass − here's why: Vue CLI CSS pre-processor option: dart-sass VS node-sass?现在您可能想知道为什么我选择node-sass而不是第一个建议的选项dart-sass - 这就是为什么: Vue CLI CSS 预处理器选项:dart-sass VS node-sass?

In package.json you are given at least these dependencies: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"
  }

With .eslintrc.js :使用.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',
  },
};

With .editorconfig :使用.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

Biased config changes for linting and formatting用于 linting 和格式化的有偏见的配置更改

So, with my biased modifications to .eslintrc.js :所以,我对.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,
      },
    },
  ],
};

Then I've added .eslintignore file:然后我添加了.eslintignore文件:

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

Then I've added this section in top of .editorconfig (while not sure if this file is needed):然后我在.editorconfig顶部添加了这个部分(虽然不确定是否需要这个文件):

# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

Installing and configuring Stylelint安装和配置 Stylelint

Stylelint is a somewhat similar project to CSS/SCSS/SASS/LESS/Stylus than ESLint is for JavaScript/TypeScript, being likewise extendable with plugins and presets. Stylelint是一个类似于 CSS/SCSS/SASS/LESS/Stylus 的项目,而不是用于 JavaScript/TypeScript 的 ESLint,同样可以通过插件和预设进行扩展。 It has an official VS Code extension, and it can also be run during your Webpack build process.它有一个官方的 VS Code 扩展,它也可以在你的 Webpack 构建过程中运行。

I've chosen to extend Stylelint with stylelint-scss package , which currently has half a million of weekly downloads, andstylelint-config-recommended-scss package from the same maintainer.我选择使用stylelint-scss package扩展 Stylelint,它目前每周有 50 万次下载,以及来自同一维护者的 stylelint-config-recommended-scss 包 In addition, I've configured stylelint-webpack-plugin as a part of the Webpack build process.此外,我已经将stylelint-webpack-plugin配置为 Webpack 构建过程的一部分。

Install these dev dependencies from the command line by: npm i -D stylelint stylelint-config-recommended-scss stylelint-scss stylelint-webpack-plugin通过以下方式从命令行安装这些开发依赖项: npm i -D stylelint stylelint-config-recommended-scss stylelint-scss stylelint-webpack-plugin

Add a file .stylelintrc.json with a few biased rule modifications as an example (Vue's ::v-deep custom selector handling may come needed):添加一个文件.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"]
      }
    ]
  }
}

Create file or add to vue.config.js , this some biased config examples:创建文件或添加到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 editor, extensions and settings VS Code 编辑器、扩展和设置

Create .vscode named folder in your project root for placing project specific settings and extension recommendations.在项目根目录中创建.vscode命名文件夹,用于放置项目特定设置和扩展建议。 Note that if you open VS Code in workspace mode (having multiple project roots included at once), some of the settings do not work in this mode, so I'm always opening the project root directly without using workspace mode.请注意,如果您在工作区模式下打开 VS Code(一次包含多个项目根目录),则某些设置在此模式下不起作用,因此我总是直接打开项目根目录而不使用工作区模式。

In this folder add a file extensions.json , with at least this content recommended, and install the extensions.在这个文件夹中添加一个文件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",
  ]
}

Add another file settings.json with these or similar settings:使用这些或类似设置添加另一个文件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,
}

So these were my biased project settings, and I'm interested in hearing improvement suggestions!所以这些是我有偏见的项目设置,我有兴趣听取改进建议!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM