描述 stylelint 与 prettier 规则冲突时的解决顺序

解读

在国内一线前端团队的 Grunt 工程里,stylelint 负责「代码质量」——校验 CSS/SCSS 语义、可维护性;prettier 负责「代码风格」——统一换行、引号、空格等格式。二者规则集存在天然交集,例如 declaration-colon-newline-aftermax-line-length 等,一旦配置不当就会出现「先格式化后校验」或「先校验后格式化」的反复报错,导致 CI 流水线卡死或本地开发体验崩塌。面试官想考察的是:你能否在 Grunt 任务编排层面给出可落地、可复现、可回滚的冲突消解顺序,并解释背后的设计哲学。

知识点

  1. 职责分离原则:prettier 只格式化,不校验;stylelint 只校验,不格式化。
  2. Grunt 任务拓扑registerTask('default', ['prettier', 'stylelint', 'build']) 的顺序决定磁盘文件最终形态。
  3. 优先级策略「先 prettier 后 stylelint」 是社区共识,因为 prettier 输出可预期且不可逆;stylelint 随后做「质检」,若仍有错误则必属代码逻辑缺陷而非风格问题。
  4. 配置互斥:通过 stylelint-config-prettier 关闭所有与 prettier 冲突的规则,保留业务强相关的校验(如 selector-class-patternplugin/selector-bem-pattern)。
  5. 缓存与增量:使用 grunt-newerstylelint --cacheprettier --list-different 降低二次运行成本,保证秒级反馈
  6. hook 卡点:在 lint-staged(配合 Grunt 子进程)或 husky pre-commit 阶段强制执行顺序,禁止「跳过 prettier 直接 commit」的灰色路径。
  7. 回滚预案:在 Gruntfile.js 中预留 grunt.option('force') 开关,紧急上线时可临时 grunt stylelint:fix --force 绕过阻断,但会在 CI 邮件中高亮告警

答案

在 Grunt 构建链条里,必须先运行 prettier 再运行 stylelint,具体步骤如下:

  1. 安装并加载 grunt-prettiergrunt-stylelint,同时引入 stylelint-config-prettier 做规则互斥。
  2. Gruntfile.js 中注册任务序列:
    grunt.registerTask('format', ['prettier']);
    grunt.registerTask('lint', ['stylelint']);
    grunt.registerTask('pre-commit', ['format', 'lint']);
    
  3. 配置 prettier 任务仅格式化 src/**/*.{css,scss,less},并开启 --list-different 实现增量;stylelint 任务开启 --fix 自动修复非冲突类问题,剩余错误则阻断提交。
  4. 通过 huskypre-commit 钩子调用 grunt pre-commit,确保顺序不可被开发者本地别名篡改
  5. 若 CI 仍报错,优先检查 stylelint 自定义插件规则是否意外开启与 prettier 冲突的项,及时在 .stylelintrc.jsextend: ['stylelint-config-prettier'] 兜底。

总结一句话:「先让 prettier 把代码拍平,再让 stylelint 做质检裁判」,既保证风格一致,又保留业务级强校验,冲突自然消解。

拓展思考

  1. monorepo 场景:子项目技术栈不同,A 项目用 scss、B 项目用 less,如何在根目录共享一份顺序配置却允许子项目自定义 stylelint 插件?
    解法:在 Gruntfile.js 里动态读取 packages/*/lint.config.js,利用 grunt.task.run(...) 动态注入任务,保证顺序不变、规则可插拔。

  2. 性能极限优化:当仓库达到 5 万行样式,prettier 全量格式化耗时 8s,stylelint 全量校验 6s,如何压缩到 2s 以内?
    可引入 grunt-concurrent 把「prettier 增量格式化」与「stylelint 增量校验」并行跑在独立 worker 进程,但需加文件锁防止同一文件并发写盘;最终仍保持「prettier 先落盘、stylelint 后校验」的逻辑顺序

  3. 未来替代方案:社区出现 stylelint-prettier 一体化插件,官方宣称可一次性完成格式+校验,是否还要坚持 Grunt 双任务顺序?
    在国内金融、政务等强审计场景,一体化插件的黑盒行为不利于审计回溯;因此即使采用新插件,也建议在 Grunt 侧显式拆分两个子任务,保留可追踪的中间态文件,以满足合规检查。