css 代码格式化工具 - Stylelint 使用指南

3,588 阅读5分钟

〇. 概述

Stylelint是一个强大、先进的CSS代码检查器, 可以帮助你规避CSS代码中的错误并保持一致的编码风格 除了.css, Stylelint还可以通过扩展来解析css预处理器语言(例如 SCSSSassLess等)以及HTMLMarkdownCSS-in-JSvue SFCs等模板文本中提取内嵌的样式代码

官方文档: stylelint.io

社区生态: github.com/stylelint/a…

一. 如何使用

1. 在编辑器中安装最新版本Stylelint扩展

2. 在项目根目录新建.vscode目录以及该目录下的settings.json文件

3. 在settings.json文件添加相应配置项:

{
  "editor.formatOnSave": true,
  "stylelint.enable": true,
  "stylelint.validate": ["css", "less", "scss", "sass", "html", "vue"],
  "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": true
  }
}

当然, 你也可以配置到全局的 settings.json 里, 不过为了团队成员的统一, 建议将这些配置到项目的 settings.json 里~

还有, 记得注释掉项目.gitignore 里的.vscode/*

4. 安装依赖

按需安装下面的依赖:

部分规则有recommendedstandard两种版本, standard是继承了相应的recommended规则并添加了额外的规则, 所以规则强度standard > recommended, 可按项目实际情况自行选择

例如stylelint-config-recommendedstylelint-config-standard

  • 基础依赖

    • postcss:转换css代码工具
    • postcss-html:识别html/vue中的<style></style>标签中的样式
    • stylelint:css样式lint工具
    • stylelint-config-standard:Stylelint官方提供的配置规则
    • stylelint-order:指定样式书写的顺序,在.stylelintrc.jsorder/properties-order指定顺序
  • vue相关依赖

    • stylelint-config-standard-vue:.vue文件的样式配置规则
  • less相关依赖

    • postcss-less:识别less语法
    • stylelint-less:stylelint-config-recommended-less的依赖,lessstylelint规则集合
    • stylelint-config-standard-less:less的配置规则
  • scss相关依赖

    • postcss-scss:识别scss语法
    • stylelint-scss:stylelint-config-standard-scss的依赖,scssstylelint规则集合
    • stylelint-config-standard-scss:scss的配置规则
  • prettier相关依赖

    • stylelint-prettier:基于prettier代码风格的stylelint规则
    • stylelint-config-prettier: 禁用所有与格式相关的Stylelint规则,解决prettierstylelint规则冲突,确保将其放在extends队列最后,这样它将覆盖其他配置

5.添加配置文件

stylelint需要一个配置对象, 支持以下位置:

  • package.json中的stylelint属性
  • .stylelintrc文件
  • .stylelintrc.{cjs,js,json,yaml,yml}文件
  • stylelint.config.{cjs,js}导出JS对象的文件

stylelint会在工作目录中寻找这些配置文件, 直到找到一个后会通知寻找, 当然, 你也可以使用--config或者configFile选项去指定配置文件

推荐使用.js.cjs文件的形式以方便自定义配置

.stylelintrc.js:

module.exports = {
  root: true,
  /* 继承其他规则, 用来扩展配置 */
  extends: [
    "stylelint-config-standard",
    ...
  ],
  /* 引入插件, 用于扩展stylelint的原生rules */
  plugins: [
    "stylelint-order"
    ...
  ],
  /* 可以为不同格式的文件分别配置 */
  overrides: [
    {
      files: ["**/*.(less|vue)"],
      /* 指定在代码上使用的自定义语法 */
      customSyntax: "postcss-less",
    },
    {
      files: ["**/*.(html|vue)"],
      customSyntax: "postcss-html",
      rules: {
        'keyframes-name-pattern': null,
        ...
      },
    },
    ...
  ],
  /* 忽略文件, 如果项目较多建议在.stylelintignore配置 */
  ignoreFiles: [
    "**/*.js",
    ...
  ],
  /* 项目个性化的规则 */
  rules: {
    "selector-class-pattern": null,
    ...
  },
};

6.添加执行脚本

命令常用选项:

  • --config: 指定包含配置对象文件的路径, 而不是让Stylelint搜索配置文件
  • --fix: 自动修复
  • --cache: 缓存已处理文件的结果, 可以显著提高Stylelint的速度
  • --cache-location: 指定缓存文件或目录的路径, 不指定则存储在默认路径./.stylelintcache
  • --ignore-path: 指定忽略文件路径, 可重复此选项以提供多个路径, 不指定则Stylelint在默认路径.stylelintignore寻找

二. 配置建议

package.json:

    "lint:style": "stylelint \"./**/*.{css,less,scss,sass,vue,html}\" --fix --cache --cache-location node_modules/.cache/stylelint/ --ignore-path .gitignore"

.stylelintrc.js:

按照vue+less+prettier配置, 请根据项目实际技术栈调整~

module.exports = {
  root: true,
  /* 继承其他规则, 用来扩展配置 */
  extends: [
    "stylelint-config-standard",
    "stylelint-config-recommended-less",
    'stylelint-config-standard-vue',
    "stylelint-config-prettier"
  ],
  /* 引入插件, 用于扩展stylelint的原生rules */
  plugins: ["stylelint-order"],
  /* 可以为不同格式的文件分别配置 */
  overrides: [
    {
      files: ['*.(less|vue)'],
      /* 指定在代码上使用的自定义语法 */
      customSyntax: 'postcss-less'
    },
    {
      files: ['*.(html|vue)'],
      customSyntax: 'postcss-html'
    }
  ],
  /* 忽略文件 */
  ignoreFiles: [
    '**/*.js',
    '**/*.jsx',
    '**/*.tsx',
    '**/*.ts',
    '**/*.json',
    '**/*.md',
    '**/*.yaml'
  ],
  /* 项目个性化的规则 */
  rules: {
    'selector-class-pattern': null, // 选择器命名模式
    'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
    'selector-pseudo-element-no-unknown': [
      true,
      {
        ignorePseudoElements: ['v-deep']
      }
    ],
    'selector-pseudo-class-no-unknown': [
      true,
      {
        ignorePseudoClasses: ['global','deep']
      }
    ],
    // 指定样式的排序
    // 定位 尺寸 文字 背景 其他
    'order/properties-order': [
      'position',
      'top',
      'right',
      'bottom',
      'left',
      'z-index',
      'display',
      'float',
      'flex-direction',
      'flex-wrap',
      'flex-flow',
      'align-content',
      'align-items',
      'justify-content',
      'order',
      'flex',
      'flex-grow',
      'flex-shrink',
      'flex-basis',
      'align-self',
      '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',
      'vertical-align',
      'text-align',
      'text-decoration',
      'text-indent',
      'text-overflow',
      'text-rendering',
      'text-size-adjust',
      'text-shadow',
      'text-transform',
      'word-break',
      'word-wrap',
      'white-space',
      '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',
    ],
  }
}