前端代码质量(3)-css校验

1,853 阅读2分钟

前言

当你书写代码时,不可避免的会产生一个错误或者多个错误。这时我们可能就需要一个工具来提示错误,或者能够直接修复这些错误。

我们将这些防止错误产生的工具叫做“linters”。JavaScript中有很好的工具,比如eslint,但是在css中,我们仅能选择基于Ruby的,具有特殊预处理程序的scss-lint(已不再维护)和较早的CSS Lint

PostCSS出现后,在其能将css语法解析为抽象语法树(AST)的基础上,集合eslint的设计思路,产生了更好的linter--stylelint

配置文件

和eslint校验类似,stylelint也有一个配置文件.stylelintrc.js(还有其他格式的,这里已js文件为例)。

module.exports = {};

规则

在stylelint中,有170+条默认关闭的内置规则,需要我们在rules中进行配置。

module.exports = {
  "rules": {
    "indentation": "tab",
    "number-leading-zero": null
  }
}

当然,这些规则我们不一定都会使用,一般使用extends来继承配置好的第三方规则stylelint-config-standard

module.exports = {
  "extends": "stylelint-config-standard",
  "rules": {
    "indentation": "tab",
    "number-leading-zero": null
  }
}

extends中可以扩展现有配置的数组,数组中的每个项目都优先于上一个项目。

rules的优先级也高于extends

plugins

plugins用于提供区别于170+条内置规则的校验规则,可以提供一个规则或一组规则。

所以,声明plugins后,需要在rules对象中为插件的规则添加配置选项。

常用的插件有(更多插件见这里):

module.exports = {
  plugins: [
    'stylelint-scss',
    'stylelint-selector-bem-pattern'
  ],
  "rules": {
       'scss/dollar-variable-pattern': '^foo',
       ...

       'plugin/selector-bem-pattern': {
          // 选择Preset Patterns,支持suit和bem两种,默认suit规范;
          // 不管哪种都需要手动指定,因为该插件未给源插件默认指定
          'preset': 'bem',
          /**
           * 自定义模式规则
           * 指定组合的选择器检查规则,其实就是指定class名称规则
           * 支持正则字符串、返回正则的函数、包含2个选项参数的对象等写法
           */
          componentSelectors: {
            // 只初始的选择器规则(可以理解为外层的class规则)
            initial: '^\\.{componentName}(?:__[-a-z]+)?(?:--[a-z]+)?$',
            // 可以理解为外层以内的选择器的规则,
            // 如果不指定,则跟initial同样的规则,
            // 注意这里配置的时候比上面少一个问号,
            // 是希望内层就不应该只有componentName作为选择器了
            combined: '^\\.{componentName}(?:__[-a-z]+)(?:--[a-z]+)?$'
          },
          "utilitySelectors": "^\\.u-[a-z]+$",
          ignoreSelectors: ['^\\.el-', '/deep/', '>>>', '^\\.icon-'],
          ignoreCustomProperties: [],
        }
   }
}

ignore

在项目中,添加.stylelintignore来设置校验规则忽略的文件。

*.js
*.png
*.eot
*.ttf
*.woff

stylelint自动忽略node_modules和bower_modules

命令行操作

在使用命令行时,设置配置项可以让我们更灵活的使用stylelint,下面是一些常用命令(更多的命令见这里)。

自动修复

在命令行中添加--fix,在可能的情况下(有些情况下无法进行修复),则可以自动修复不满足规则的css代码。

stylelint **/*.css --fix

对于具有标准语法的CSS,stylelint使用postcss-safe-parser修复语法错误。

缓存

--cache能存储已处理文件的结果,以便stylelint仅对更改后的文件起作用。

stylelint **/*.css --fix --cache

自动化

VS Code插件

上面我们说到使用--fix可以自动修复css,但是在重新开发代码后,需要再执行一次命令。本着尽可能使用工具,我们可以使用vs code编辑器中的stylelint插件来自动修复。

下载完毕后,这时我们还需要在.vscode/settings.json或者【设置】中添加以下信息:

{
  "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": true
  }
}

这样,在保存文件时,会按照stylelint自动修复代码。

git commit验证

除了编辑器自动进行校验stylelint,我们再本地提交commit时也可以进行相关校验。 这里,我们使用huskylint-staged

pre-commit这个钩子由git commit调用,可以使用--no-verify选项绕过它。它不接受任何参数,并在获取建议的提交日志消息和进行提交之前被调用。从这个脚本中退出非零状态会导致git commit命令在创建提交之前中止。

// 下载npm
npm install --save-dev husky lint-staged

// package.json
{
    "husky": {
        "hooks": {
          "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "*": ["stylelint --fix", "git add"],
    },
}

CI校验

在上面我们了解到pre-commit钩子可以通过--no-verify绕过,所以我们在gitlab中还需要添加pipelines用于自动校验,并将校验结果及时反馈。

最佳实践

这里的最佳实践,是说我们项目的实际使用情况的整理。大家在自己项目中按各自情况来调整。

  1. 下载npm
npm install --save-dev stylelint stylelint-config-standard stylelint-selector-bem-pattern husky lint-staged
  1. 配置stylelint
// .stylelintrc.js
module.exports = {
  "extends": "stylelint-config-standard",
  plugins: [
    'stylelint-scss',
    'stylelint-selector-bem-pattern'
  ],
  "rules": {
       'scss/dollar-variable-pattern': '^foo',
       ...

       'plugin/selector-bem-pattern': {
          'preset': 'bem',
          componentSelectors: {
            initial: '^\\.{componentName}(?:__[-a-z]+)?(?:--[a-z]+)?$',
            combined: '^\\.{componentName}(?:__[-a-z]+)(?:--[a-z]+)?$'
          },
          "utilitySelectors": "^\\.u-[a-z]+$",
          ignoreSelectors: ['^\\.el-', '/deep/', '>>>', '^\\.icon-'],
          ignoreCustomProperties: [],
        }
   }
}
  1. 在vscode中添加stylelint插件
  2. 设置stylelint插件的相关信息
// .vscode/settings.json
{
  "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": true
  }
}
  1. git commit校验
// package.json
{
    "husky": {
        "hooks": {
          "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "*": ["stylelint --fix", "git add"],
    },
}

参考