写给自己看的lint规则

由 漆黑菌 于 2023年05月04日 发布

依赖

基于vue-cli+Airbnb规则+typescript生成模版,加入eslint-plugin-import、eslint-plugin-jsonc和eslint-plugin-lodash。eslint-plugin-lodash可以通过lodash/import-scope提示使用import functionName from ‘lodash/functionName’ 的最小打包引入方式

stylelint规则

关闭对-webkit-box和color现代写法的限制

{
  "value-no-vendor-prefix": [
      true,
      {
        "ignoreValues": [
          "box"
        ]
      }
    ],
    "color-function-notation": "legacy"
}

eslint规则

const { dependencies: { vue: vueVersion } } = require('./package.json');

module.exports = {
  reportUnusedDisableDirectives: true,
  root: true,
  env: {
    'shared-node-browser': true,
    node: true,
    browser: true,
    worker: true,

  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    ecmaVersion: 'latest',
    ecmaFeatures: {
      jsx: true,
    },
    parser: '@typescript-eslint/parser',
    extraFileExtensions: ['.vue'],

  },
  plugins: [
    'vue',
    '@typescript-eslint',
    'lodash',
  ],
  extends: [
    'plugin:jsonc/recommended-with-json',
    'plugin:vue/essential',
    'plugin:vue/recommended',
    '@vue/typescript/recommended',
  ],
  rules: {
    'jsonc/indent': ['error', 2],

    // `vue/max-len` needs special configuration for better usability
    'vue/max-len': ['error', 100, 2, {
      ignoreUrls: true,
      ignoreComments: true,
      ignoreRegExpLiterals: true,
      ignoreStrings: true,
      ignoreTemplateLiterals: true,

      // 1. it's like `ignoreStrings`
      // 2. SVG `path`s should be ignored
      ignoreHTMLAttributeValues: true,
      // Because spaces in HTML are insignificant,
      // it shouldn't be hard to start a new line for text content
      ignoreHTMLTextContents: true,
    }],
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    '@typescript-eslint/no-require-imports': 'off',
    'vue/multi-word-component-names': 'off',
    'vue/component-name-in-template-casing': ['error'],
    'vue/component-options-name-casing': ['error'],
    // 在vue2中推荐使用 kebab-case 详情见文档
    'vue/custom-event-name-casing': ['error', 'camelCase'],
    'vue/html-comment-content-newline': ['error'],
    'vue/match-component-file-name': ['warn', {
      extensions: ['jsx', 'tsx', 'vue'],
      shouldMatchCase: false,
    }],
    'vue/no-boolean-default': ['error', 'default-false'],
    'vue/no-duplicate-attr-inheritance': ['error'],
    'vue/no-empty-component-block': ['error'],
    'vue/no-multiple-objects-in-class': ['error'],
    'vue/no-potential-component-option-typo': ['error'],
    'vue/no-restricted-call-after-await': ['error'],
    'vue/no-static-inline-styles': ['warn'],
    'vue/no-this-in-before-route-enter': ['error'],
    'vue/no-unsupported-features': ['error', {
      version: vueVersion,
    }],
    'vue/no-unused-refs': ['warn'],
    'vue/no-useless-mustaches': ['error', {
      ignoreIncludesComment: false,
      ignoreStringEscape: true,
    }],
    'vue/padding-line-between-blocks': 'error',
    'vue/prefer-prop-type-boolean-first': 'error',
    'vue/prefer-separate-static-class': 'error',
    'vue/prefer-true-attribute-shorthand': 'error',
    'vue/require-name-property': 'error',
    'vue/script-indent': ['error', 2],
    'vue/v-for-delimiter-style': ['error', 'in'],
    'brace-style': ['error', '1tbs'],
    'eol-last': ['error', 'always'],
    'comma-spacing': [
      'error',
      {
        before: false,
        after: true,
      },
    ],
    quotes: ['error', 'single'],
    'jsx-quotes': ['error', 'prefer-double'],
    'vue/html-quotes': ['error', 'double', { avoidEscape: true }],
    'max-statements-per-line': ['error', { max: 1 }],
    'vue/multiline-html-element-content-newline': ['error'], // 多行html中的内容是否独占一行
    'vue/singleline-html-element-content-newline': ['error'],
    'vue/max-attributes-per-line': ['error', {
      singleline: {
        max: 1,
      },
      multiline: {
        max: 1,
      },
    }],
    'array-element-newline': ['error', 'consistent'],
    'array-bracket-newline': ['error', 'consistent'], // []新一行
    'vue/array-bracket-newline': ['error', 'consistent'],
    'comma-dangle': ['error', 'always-multiline'], // 最后一个对象元素加逗号
    'object-property-newline': ['error', { allowAllPropertiesOnSameLine: false }],
    'vue/object-property-newline': ['error', { allowAllPropertiesOnSameLine: false }],
    'vue/space-infix-ops': ['error', { int32Hint: true }],
    'vue/object-curly-spacing': ['error', 'always'], // 对象内的间距要求
    'vue/comma-spacing': ['error'], // 对象内的逗号位置
    'vue/key-spacing': ['error'], // 冒号位置
    'vue/camelcase': [
      'off',
    ],
    camelcase: [
      'off',
    ],

    // lodash
    'lodash/callback-binding': ['error'],
    'lodash/collection-method-value': ['error'],
    'lodash/collection-return': ['error'],
    'lodash/no-double-unwrap': ['error'],
    'lodash/no-extra-args': ['error'],
    'lodash/no-unbound-this': ['error'],
    'lodash/unwrap': ['error'],
    'lodash/import-scope': ['error'],
  },
  overrides: [
    {
      files: ['*.json', '*.json5', '*.jsonc'],
      parser: 'jsonc-eslint-parser',
    },
  ],
};