StyleLint

重要通知

如果您使用 StyleLint,请安装 stylelint-config-prettier 以使 StyleLint 和 Prettier 彼此配合得很好。它会关闭所有不必要的或可能与 Prettier 冲突的 StyleLint 规则。

基本概况

StyleLint是一个强大的现代代码检查工具,可以帮助您避免错误并在您的样式中强制执行约定。

> yarn add -D postcss
> yarn add -D stylelint stylelint-config-standard # Stylelint标准配置
> yarn add -D stylelint-config-prettier -D #  prettier规范
> yarn add -D postcss-html stylelint-config-html # 
> yarn add -D stylelint-order stylelint-config-rational-order # 支持css 属性顺序
> yarn add -D stylelint-config-recommended-vue # 支持vue 文件
> yarn add -D stylelint-config-prettier # 关闭所有不必要的或可能与 Prettier 冲突的规则
> yarn add -D postcss-scss stylelint-scss stylelint-config-standard-scss # 支持 Scss
> yarn add -D postcss-less stylelint-less # 支持 Less
  • 命令行运行
> stylelint "src/App.vue" --fix # 对某个文件进行检查
> stylelint "src/*.{html,vue,css,saas,scss,less}" --fix # 对指定后缀名的文件进行检查
  • 配置.vscode/setting.json
{
  "stylelint.validate": ["css", "postcss", "less", "scss", "sass", "vue"]
}
  • 注意事项
    • stylelint 无法识别 :deep伪类
    • stylelint 的 class 命名规范默认为使用中划线分割,而elemsntui 使用的是 bem的规范
module.exports = {
  rules:{
    'selector-class-pattern':'^([a-z][a-z0-9]*)(-+[a-z0-9]+)*$',
    'selector-pseudo-class-no-unknown':[true, {
      ignorePseudoClasses: ["deep"]
    }]
  }
}

基础知识

  • 加载配置优先级

    • package.json 中的 stylelint 属性
    • .stylelintrc 文件
    • 导出JS对象的 stylelint.config.js 文件
  • 关闭规则

可以通过在CSS中使用特殊注释暂时关闭规则。例如,您可以关闭所有规则

/* stylelint-disable */
a {}
/* stylelint-enable */

关闭个别规则

/* stylelint-disable selector-no-id, declaration-no-important  */
#id {
  color: pink !important;
}
  • 配置规则
    • 单个值(主选项),指定主选项将(启用规则)。
    • 包含两个值的数组([主选项, 辅助选项])(启用规则)。
    • null(关闭规则)

package.json

{
  "scripts": {
    "lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/"
  },

  // 在git commit 的时候对文件进行校验
  "lint-staged": {
      "**/*.{css,less,scss,vue}":[
      "npm run lint:stylelint",
      "git add ."
    ]
  },
  "stylelint": {}
}

.stylelintignore

.stylelintignore文件中的模式必须与 .gitignore 语法匹配。

public
node_modules
.history
.husky
dist
*.d.ts
package.json

stylelint.config.js

module.exports = {
  root: true,
  plugins: [
    'stylelint-order',
    'stylelint-scss'
  ],
  customSyntax: 'postcss-html',
  // 如果extends中包含多个配置项,那么数组中的每一项都优先于前一项,也就是说第二项会覆盖第一项,第三项会覆盖第一项和第二项,最后一项将覆盖其它所有项。
  extends: ['stylelint-config-standard', 'stylelint-config-html', "stylelint-config-recommended-vue"],
  ignoreFiles: [
    '**/*.js', 
    '**/*.jsx', 
    '**/*.tsx', 
    '**/*.ts'
  ],
  overrides: [
    // 若项目中存在scss文件,添加以下配置
    {
      files: '**/*.scss',
      customSyntax: 'postcss-scss',
    },
    // 若项目中存在less文件,添加以下配置
    {
      files: '**/*.less',
      customSyntax: 'postcss-less',
    },
  ],
  rules: {
    // 颜色
    "color-no-invalid-hex": true, // 禁止无效的 16 进制颜色。
    "color-named": "never", // 要求(如果可能)或禁止命名颜色。
    "color-no-hex": false, // 禁止 16 进制颜色。
    "color-hex-case": "lower", // 指定 16 进制颜色的大小写(可自动修复)。

    // 字体族
    "font-family-no-duplicate-names": true, // 禁止重复的字体族名称。
    "font-family-no-missing-generic-family-keyword": true, // 禁止在字体族名称列表中缺少通用字体族关键字。

    // 函数
    "function-calc-no-invalid": true, // 禁止在 calc 函数中使用无效表达式。
    "function-calc-no-unspaced-operator": true, // 禁止在 calc 函数中使用没有间隔的运算符。
    "function-linear-gradient-no-nonstandard-direction": true, // 禁止在 linear-gradient() 中调用不符合标准语法的无效方向值。
    "function-blacklist": [], // 指定禁用的函数的黑名单。
    "function-url-no-scheme-relative": true, // 禁止相对协议 URL。
    "function-url-scheme-blacklist": ["ftp"], // 指定禁用的 URL 协议的黑名单。
    "function-url-scheme-whitelist": [], // 指定允许的 URL 协议的白名单。

    "function-comma-space-after": "always", // 要求在函数的逗号之后必须有一个空格或不能有空白符(可自动修复)。
    "function-comma-space-before": "never", // 要求在函数的逗号之前必须有一个空格或不能有空白符(可自动修复)。
    "function-max-empty-lines": 0, // 限制函数中相邻空行的数量(可自动修复)
    "function-name-case": "lower", // 指定函数名的大小写(可自动修复)。
    "function-parentheses-newline-inside": "never-multi-line", // 要求在函数的括号内侧必须有换行符或不能有空白符(可自动修复)。
    "function-parentheses-space-inside": "never", // 要求在函数的括号内侧必须有一个空格或不能有空白符(可自动修复)。
    "function-url-quotes": "always", // 要求或禁止 URL 的引号。
    "function-whitespace-after": "always", // 要求或禁止函数之后的空白符(可自动修复)。

    // 字符串
    "string-no-newline": true, // 禁止字符串中的(未转义)换行符。

    // 单位
    "unit-no-unknown": true, // 禁止未知的单位。

    // 属性
    "property-no-unknown": true, // 禁止未知的属性。

    // 关键帧声明
    "keyframe-declaration-no-important": true, // 禁止关键帧声明的 !important。

    // 声明块
    "block-no-empty": true, // 禁止空块
    "rule-empty-line-before": "never", // 要求或禁止在规则之前的空行。
    "declaration-block-no-duplicate-properties": true, // 禁止声明块的重复属性。
    "declaration-block-no-shorthand-property-overrides": true, // 禁止简写属性覆盖相关的扩写属性。
    "declaration-block-single-line-max-declarations": 5, // 限制一个单行声明块中声明的数量
    "declaration-block-semicolon-newline-after": "always", // 要求在声明块的分号之后必须有换行符或不能有空白符(可自动修复)。
    "declaration-block-semicolon-newline-before": "always", // 要求在声明块的分号之前必须有换行符或不能有空白符。
    "declaration-block-semicolon-space-after": "always", // 要求在声明块的分号之后必须有一个空格或不能有空白符(可自动修复)。
    "declaration-block-semicolon-space-before": "never", // 要求在声明块的分号之前必须有一个空格或不能有空白符(可自动修复)。
    "declaration-block-trailing-semicolon": "always", // 要求或禁止声明块的一个尾随分号(可自动修复)。

    "block-closing-brace-empty-line-before": "never", // 要求或禁止在块的闭大括号之前空行(可自动修复)。
    "block-closing-brace-newline-after": "always", // 要求在块的闭大括号之后必须有换行符或不能有空白符(可自动修复)。
    "block-closing-brace-newline-before": "never-multi-line", // 要求在块的闭大括号之前必须有换行符或不能有空白符(可自动修复)。
    "block-closing-brace-space-after": "never", // 要求在块的闭大括号之后必须有一个空格或不能有空白符。
    "block-closing-brace-space-before": "always", // 要求在块的闭大括号之前必须有一个空格或不能有空白符(可自动修复)。
    "block-opening-brace-newline-before": "always", // 要求在块的开大括号之前必须有换行符或不能有空白符(可自动修复)。
    "block-opening-brace-space-after": "always", // 要求在块的开大括号之后必须有一个空格或不能有空白符(可自动修复)。
    "block-opening-brace-space-before": "always", // 要求在块的开大括号之前必须有一个空格或不能有空白符(可自动修复)。

    // 选择器
    "selector-pseudo-class-no-unknown": true, // 禁止未知的伪类选择器。
    "selector-pseudo-element-no-unknown": true, // 禁止未知的伪元素选择器。
    "selector-type-no-unknown": true, // 禁止未知的类型选择器。

    "selector-attribute-brackets-space-inside": "never", // 要求在属性选择器的中括号内侧必须有一个空格或不能有空白符(可自动修复)。
    "selector-attribute-operator-space-after": "always", // 要求在属性选择器中的运算符之后必须有一个空格或不能有空白符(可自动修复)。
    "selector-attribute-operator-space-before": "always", // 要求在属性选择器中的运算符之前必须有一个空格或不能有空白符(可自动修复)。
    "selector-attribute-quotes": "always", // 要求或禁止属性值的引号。
    "selector-combinator-space-after": "always", // 要求在组合选择器之后必须有一个空格或不能有空白符(可自动修复)。
    "selector-combinator-space-before": "always", // 要求在组合选择器之前必须有一个空格或不能有空白符(可自动修复)。
    "selector-descendant-combinator-no-non-space": true, // 禁止后代选择器使用非空格字符(可自动修复)。
    "selector-pseudo-class-case": "lower", // 指定伪类选择器的大小写(可自动修复)。
    "selector-pseudo-class-parentheses-space-inside": "never", // 要求在伪类选择器的括号内侧必须有一个空格或不能有空白符(可自动修复)。
    "selector-pseudo-element-case": "lower", // 指定伪元素选择器的大小写。
    "selector-pseudo-element-colon-notation": "single", // 指定伪元素适用单冒号还是双冒号表示法(可自动修复)。
    "selector-type-case": "lower", // 指定类型选择器的大小写(可自动修复)。

    "selector-list-comma-newline-before": "never-multi-line", // 要求在选择器列表的逗号之前必须有换行符或不能有空白符(可自动修复)。
    "selector-list-comma-space-after": "always", // 要求在选择器列表的逗号之后必须有一个空格或不能有空白符(可自动修复)。
    "selector-list-comma-space-before": "never", // 要求在选择器列表的逗号之前必须有一个空格或不能有空白符(可自动修复)。

    // 媒体功能
    "media-feature-name-no-unknown": true, // 禁止未知的媒体功能名。

    "media-feature-colon-space-after": "always", // 要求在媒体功能的冒号之后必须有一个空格或不能有空白符(可自动修复)。
    "media-feature-colon-space-before": "never", // 要求在媒体功能的冒号之前必须有一个空格或不能有空白符(可自动修复)。
    "media-feature-name-case": "lower", // 指定媒体功能名的大小写(可自动修复)。
    "media-feature-parentheses-space-inside": "never", // 要求在媒体功能的括号内侧必须有一个空格或不能有空白符(可自动修复)。
    "media-feature-range-operator-space-after": "always", // 要求在媒体功能的范围运算符之后必须有一个空格或不能有空白符(可自动修复)。
    "media-feature-range-operator-space-before": "always", // 要求在媒体功能的范围运算符之前必须有一个空格或不能有空白符(可自动修复)。

    "media-query-list-comma-newline-before": "never-multi-line", // 要求在媒体查询列表的逗号之前必须有换行符或不能有空白符。
    "media-query-list-comma-space-after": "always", // 要求在媒体查询列表的逗号之后必须有一个空格或不能有空白符(可自动修复)。
    "media-query-list-comma-space-before": "never", // 要求在媒体查询列表的逗号之前必须有一个空格或不能有空白符(可自动修复)。

    // ####@规则
    "at-rule-no-unknown": true, // 禁止未知的@规则。
    "at-rule-empty-line-before": "always", // 要求或禁止在@规则之前的空行(可自动修复)。
    "at-rule-name-case": "lower", // 指定@规则名的大小写(可自动修复)。
    "at-rule-name-space-after": "always-single-line", // 要求在@规则名之后必须有一个空格(可自动修复)。
    "at-rule-semicolon-newline-after": "always", // 要求在@规则的分号之后必须有换行符(可自动修复)。
    "at-rule-semicolon-space-before": "never", // 要求在@规则的分号之前必须有一个空格或不能有空白符。

    // 注释
    "comment-no-empty": true, // 禁止空注释。

    // 一般/表
    "no-descending-specificity": true, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器。
    "no-duplicate-at-import-rules": true, // 禁止在样式表中使用重复的 @import 规则。
    "no-duplicate-selectors": true, // 禁止样式表中的重复选择器。
    "no-empty-source": true, // 禁止空源码。
    "no-extra-semicolons": true, // 禁止额外的分号(可自动修复)。
    "no-invalid-double-slash-comments": true, // 禁止 CSS 不支持并可能导致意外结果的双斜杠注释(//...)。
    "max-nesting-depth": 10, // 限制允许的嵌套深度。
    "no-unknown-animations": true, // 禁止未知的动画。

    "indentation": 2, // 指定缩进(可自动修复)。
    "linebreaks": "unix", // 指定 unix 或 windows 换行符(可自动修复)。
    "max-empty-lines": 2, // 限制相邻空行的数量。
    "max-line-length": 80, // 限制行的长度。
    "no-eol-whitespace": true, // 禁止行尾空白符(可自动修复)。
    "no-missing-end-of-source-newline": true, // 禁止缺少源码结尾换行符(可自动修复)。
    "no-empty-first-line": true, // 禁止空第一行(可自动修复)。

    // 关键帧
    "keyframes-name-pattern": "ani-custom", // 指定关键帧名的模式。

    // 声明
    "declaration-bang-space-after": "always", // 要求在声明的叹号之后必须有一个空格或不能有空白符(可自动修复)。
    "declaration-bang-space-before": "always", // 要求在声明的叹号之前必须有一个空格或不能有空白符(可自动修复)。
    "declaration-colon-space-after": "always", // 要求在声明块的冒号之后必须有一个空格或不能有空白符(可自动修复)。
    "declaration-colon-space-before": "never", // 要求在声明块的冒号之前必须有一个空格或不能有空白符(可自动修复)。
    "declaration-empty-line-before": "never", // 要求或禁止在声明之前的空行(可自动修复)。

    // 注释
    "comment-empty-line-before": "always", // 要求或禁止在注释之前的空行(可自动修复)。
    "comment-whitespace-inside": "always", // 要求或禁止注释标记内侧的空白符(可自动修复)。

    // Specify the alphabetical order of the attributes in the declaration block
    'order/properties-order': [
      'position',
      'top',
      'right',
      'bottom',
      'left',
      'z-index',
      'display',
      'float',
      'width',
      'height',
      'max-width',
      'max-height',
      'min-width',
      'min-height',
      'padding',
      'padding-top',
      'padding-right',
      'padding-bottom',
      'padding-left',
      'margin',
      'margin-top',
      'margin-right',
      'margin-bottom',
      'margin-left',
      'margin-collapse',
      'margin-top-collapse',
      'margin-right-collapse',
      'margin-bottom-collapse',
      'margin-left-collapse',
      'overflow',
      'overflow-x',
      'overflow-y',
      'clip',
      'clear',
      'font',
      'font-family',
      'font-size',
      'font-smoothing',
      'osx-font-smoothing',
      'font-style',
      'font-weight',
      'hyphens',
      'src',
      'line-height',
      'letter-spacing',
      'word-spacing',
      'color',
      'text-align',
      'text-decoration',
      'text-indent',
      'text-overflow',
      'text-rendering',
      'text-size-adjust',
      'text-shadow',
      'text-transform',
      'word-break',
      'word-wrap',
      'white-space',
      'vertical-align',
      'list-style',
      'list-style-type',
      'list-style-position',
      'list-style-image',
      'pointer-events',
      'cursor',
      'background',
      'background-attachment',
      'background-color',
      'background-image',
      'background-position',
      'background-repeat',
      'background-size',
      'border',
      'border-collapse',
      'border-top',
      'border-right',
      'border-bottom',
      'border-left',
      'border-color',
      'border-image',
      'border-top-color',
      'border-right-color',
      'border-bottom-color',
      'border-left-color',
      'border-spacing',
      'border-style',
      'border-top-style',
      'border-right-style',
      'border-bottom-style',
      'border-left-style',
      'border-width',
      'border-top-width',
      'border-right-width',
      'border-bottom-width',
      'border-left-width',
      'border-radius',
      'border-top-right-radius',
      'border-bottom-right-radius',
      'border-bottom-left-radius',
      'border-top-left-radius',
      'border-radius-topright',
      'border-radius-bottomright',
      'border-radius-bottomleft',
      'border-radius-topleft',
      'content',
      'quotes',
      'outline',
      'outline-offset',
      'opacity',
      'filter',
      'visibility',
      'size',
      'zoom',
      'transform',
      'box-align',
      'box-flex',
      'box-orient',
      'box-pack',
      'box-shadow',
      'box-sizing',
      'table-layout',
      'animation',
      'animation-delay',
      'animation-duration',
      'animation-iteration-count',
      'animation-name',
      'animation-play-state',
      'animation-timing-function',
      'animation-fill-mode',
      'transition',
      'transition-delay',
      'transition-duration',
      'transition-property',
      'transition-timing-function',
      'background-clip',
      'backface-visibility',
      'resize',
      'appearance',
      'user-select',
      'interpolation-mode',
      'direction',
      'marks',
      'page',
      'set-link-source',
      'unicode-bidi',
      'speak'
    ]
  }
};

stylelint-config-prettier

关闭所有不必要的规则或可能与 Prettier 冲突的规则。这使您可以使用自己喜欢的可共享配置,而不会在使用Prettier时使其样式选择成为障碍。

注意事项

从 Stylelint v15 开始,所有与样式相关的规则都已被弃用。如果您使用的是 v15 或更高版本并且没有使用这些已弃用的规则,则不再需要此插件。

Last Updated:
Contributors: 709992523, Eshen