用 StyleLint 提升代码质量的实战经验分享

南宫振岚 前端 阅读 2,943
赞 10 收藏
二维码
手机扫码查看
反馈

先说结论:StyleLint + SCSS 是我团队的标配

别整那些花里胡哨的,我们项目现在统一用 StyleLint 配合 SCSS 做样式校验,配合 Prettier 格式化,跑在 pre-commit 里。虽然有人还在用 ESLint 的 style 插件,或者干脆不写 lint,但我得说一句:真不行。

用 StyleLint 提升代码质量的实战经验分享

最近带新人的时候发现,有人还是搞不清 StyleLint 和其他方案到底差在哪,就想着干脆写篇对比文,把我踩过的坑、试过的方案都拎出来讲讲。不是那种“各有优劣”的和稀泥分析,是我个人实战后的看法,有不同意见欢迎评论区对线。

为什么我要用 StyleLint?因为样式真的能写成屎

你有没有遇到过这种 CSS:

  • 颜色全写死 #333、#666,没人知道这代表啥
  • class 名瞎起,什么 .box1、.div2,重构时根本不敢动
  • 嵌套层级深到 5 层以上,一改就崩
  • 一个按钮写了三遍 hover 效果,因为拼写不一致

这些都不是代码逻辑问题,但它们会直接拖垮团队协作效率。我就在两个项目里吃过亏:一个是纯手写 CSS 没规范,最后交接时花了三天才理清命名规则;另一个是用了 PostCSS 插件做简单校验,结果根本不支持自定义规则。

所以后来我铁了心要上 StyleLint —— 它能让你的样式代码也拥有“语法洁癖”。

三种主流方案实测对比

目前前端圈常见的样式检查方案大概就这几种:

  • 纯靠人工 Code Review(别笑,真有人这么干)
  • ESLint 的 react/style 插件(比如 eslint-plugin-jsx-a11y)
  • PostCSS 自定义插件做校验
  • StyleLint(本文重点)

下面一个个说。

人工 Review?省省吧,不可能每次都看出来

这个就不放代码了,太真实反而尴尬。简单说就是依赖人眼扫描每一个 commit diff,指望同事发现问题。

问题是:人都会累,而且注意力有限。我之前参与的一个紧急项目,连续两周加班到凌晨,Code Review 全靠“差不多得了”,结果上线后发现一堆 z-index 写成了字符串,浏览器直接忽略……

这类低级错误完全可以通过工具拦截,非要用人力扛,纯属浪费生命。

ESLint 能不能搞定样式?半吊子水平

很多人以为 ESLint 插件能覆盖样式问题,比如 eslint-plugin-reactjsx-a11y 可以检查 inline-style 是否符合可访问性。

比如这样:

// React 组件中的内联样式
function Button() {
  return (
    <button style={{ backgroundColor: '#ff0000', color: '#ffffff' }}>
      提交
    </button>
  );
}

ESLint 确实可以提醒你用了 magic number 颜色,但它只能查 JSX 里的 style 对象,对于外部 CSS 文件完全无能为力。

更别说 SCSS、Less 这种预处理器,ESLint 根本看不懂。想让它识别 .scss 文件?得配一堆 parser,折腾半天还报错。

结论:适合极简项目或临时原型,正式项目别指望它。

PostCSS 插件自己写校验?可以但没必要

我知道有些团队喜欢造轮子,比如写个 PostCSS 插件来检测变量使用情况。

// postcss-plugin-no-magic-color.js
module.exports = () => {
  return {
    postcssPlugin: 'no-magic-color',
    Declaration(decl) {
      if (decl.value.includes('#') && !decl.value.includes('var(')) {
        decl.warn(this.result, '禁止直接使用十六进制颜色');
      }
    }
  };
};

然后在 postcss.config.js 中引入:

module.exports = {
  plugins: [
    require('./postcss-plugin-no-magic-color')
  ]
};

这个方案确实能跑通,我也试过。但问题来了:

  • 每加一条规则就得写一个插件
  • 没法复用社区生态(比如 stylelint-config-standard)
  • 错误提示不够友好,还得自己处理报告格式
  • 调试麻烦,console.log 都要重启构建流程

折腾了两天,我发现同样的功能 StyleLint 几行配置就能实现,何必重复造轮子?

StyleLint 真香在哪?规则全、生态强、可扩展

回到主角。StyleLint 的核心优势是:它就是一个专为样式设计的 Linter,就像 ESLint 之于 JS。

先上基础配置:

{
  "extends": "stylelint-config-standard",
  "rules": {
    "color-hex-length": "short",
    "selector-class-pattern": "^[a-z][a-zA-Z0-9]*$",
    "declaration-block-no-redundant-longhand-properties": true,
    "no-descending-specificity": null
  }
}

再配合 .stylelintignore 忽略第三方库:

node_modules/
dist/
vendor/
*.min.css

然后在 package.json 加脚本:

{
  "scripts": {
    "lint:styles": "stylelint "src/**/*.scss"",
    "lint:styles:fix": "stylelint "src/**/*.scss" --fix"
  }
}

还可以集成到编辑器,保存自动 fix。VS Code 装 stylelint 插件就行,开箱即用。

重点是它的规则系统非常灵活。比如我们团队要求所有 class 名必须驼峰式,我就直接改 selector-class-pattern:

"selector-class-pattern": "^[a-z][a-zA-Z0-9]*$"

如果想禁用某些烦人的规则,比如 no-descending-specificity(这条经常误报),直接设为 null 就行,不像 PostCSS 那样要重写逻辑。

和 Prettier 集成要注意!顺序错了直接打架

这里注意我踩过好几次坑:StyleLint 和 Prettier 都能格式化代码,但如果配置不当,会互相覆盖。

正确做法是让 Prettier 专注格式,StyleLint 专注规则,通过 stylelint-config-prettier 关闭所有与 Prettier 冲突的规则。

npm install --save-dev stylelint-config-prettier
{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-prettier"
  ]
}

同时确保执行顺序:

"lint:styles": "stylelint "src/**/*.scss" --fix && prettier "src/**/*.scss" --write"

先 StyleLint 修复结构性问题,再用 Prettier 统一缩进换行。反过来的话,Prettier 改完可能又被 StyleLint 判为不合规,无限循环。

SCSS 支持完美吗?基本够用,个别坑要绕

我们项目用的是 SCSS,StyleLint 对 @mixin、@include、变量这些支持都不错。但有一个小坑:如果你用了大量嵌套,且开启 max-nesting-depth 规则,要注意它不会穿透条件语句。

.card {
  &__title {
    font-size: 16px;

    @media (min-width: 768px) {
      font-size: 18px;

      small {
        font-size: 14px; // 这一层会被算作第3层
      }
    }
  }
}

上面这段,small 是嵌套第3层。如果 max-nesting-depth 设为2,就会报错。解决办法要么放宽限制,要么拆分结构。

我个人选择后者 —— 毕竟深层嵌套本身就不利于维护,借着 lint 强制重构也是好事。

我的选型逻辑:宁可严一点,也不能松

总结一下我的偏好:

  • 不用人工 Review 做主要防线 —— 不可靠
  • 不用 ESLint 查样式 —— 能力边界太窄
  • 不用自研 PostCSS 插件 —— 成本高,难维护
  • 主推 StyleLint + SCSS + Prettier 组合 —— 生态成熟,配置简单

虽然改完后仍有一两个小问题,比如某些动态生成的 class 会被误伤,但整体收益远大于成本。

这个方案不是最优的,但最简单、最容易落地。尤其适合中大型项目或多人协作场景。

以上是我的对比总结,有不同看法欢迎评论区交流

我知道肯定有人坚持用别的方案,比如 Tailwind 的 className 校验工具,或者用 TypeScript 编译时检查 styled-components。那些也都有道理,但在传统 SCSS/CSS 项目里,StyleLint 依然是我心中的首选。

这个技巧的拓展用法还有很多,比如结合 CI 流程做 PR 拦截、生成违规统计报表,后续会继续分享这类实战经验。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论