如何为你的 Vue 项目添加配置 Stylelint

现在已经是 9102 年了,网上许多教程和分享帖都已经过期,照着他们的步骤来会踩一些坑,如 stylelint-processor-html 已经不再维护,以及 --fix 之后 .vue 文件只剩下 <style> 部分等。我在踩完坑跑通出满意的效果后,维护一份新的指引,以备后续项目使用,顺便分享一下。

为什么选择用 stylelint ?

这个问题有两层含义,一是为什么要使用这个样式代码风格检查工具,二是与其他工具相比,为什么选择 stylelint 而不是其他如 stylefmt 等。

使用 linter 的原因

对于第一个问题,相信很多小伙伴都会被历史遗留的,或多人协同开发写下的风格不一的样式代码困扰过,最基本的就是换行、缩进和空格之争,大家对此应该都不陌生。特别是有时候你可能会遇上如下祖传代码:

#idA .classB,.classC{position:absolute;top: 0;left:0; display:-webkit-flex;display: flex;width:100%;background:url(../pic.png) no-repeat;-webkit-background-size:contain;background-size:contain }

这段代码从我个人风格来看存在不少问题:

  1. 不推荐使用 id 选择器来定义样式;
  2. 多重选择器(multiple selectors)没有换行,不清晰直观;
  3. 多个 css 规则没有换行,挤在单行太长;
  4. 使用了 -webkit- 前缀,但是项目中已经支持 autoprefixer
  5. 属性和值之间的空格时有时无等。

当然代码风格因人而异,所以才需要团队统一。在一些早期缺乏完善的代码评审等制度的项目中,很容易由于程序员的偷懒图方便或在一时的紧急粗糙赶工中积累下一坨对团队其他成员不太友好、可阅读性低、较难维护的 css 。

同类工具比较

至于第二个问题,选择 stylelint 的原因也很简单,它是当前所有同类工具中使用人数最多的,社区较为活跃,仍在持续维护。而且正如这个 issue 中提到,当下很多大厂都在使用,如 github 的 primer 体系就定制了一套自己的规则 stylelint-config-primer

至于 stylefmt 也曾经被推荐与 stylelint 搭配组合,不少博文都有提到。但是官方已经不推荐继续使用,直接用 stylelint 的 --fix 选项即可。

NOTICE: Consider other tools before adopting stylefmt

If you are using stylefmt with stylelint configuration to format according to its rules, you can now use stylelint's --fix option (from v7.11.0) to autofix.

Another on the other hand, prettier supports to format not only JavaScript but also CSS, SCSS and Less code.

而没有考虑 prettier 的原因则是它希望提供一套官方自己认可的统一风格规范,而不仅仅是个 linter 或者 formatter ,可配置项很少,定制自由度较低,不适合想要自己搞事情的团队,更适合个人开发者去使用。

如何开始使用

安装依赖

其实官方的 User guide 已经很全面,与 eslint 是非常相似的。

  1. 安装 stylelint

    npm i -D stylelint stylelint-config-stand

    后者 stylelint-config-stand 不是必需的,也可以自己根据文档从零开始配置规则,或者用第三方如 github 的规则 stylelint-config-primer

  2. 安装适配预处理语法的插件

    以 sass 为例:

    npm i -D stylelint-scss

    不过 stylus 目前没有发现可用性高的相关插件,也导致 stylelint 不能解析 stylus 语法。

  3. 安装 webpack 插件

    npm i -D stylelint-webpack-plugin

命令行使用

stylelint 搜索目录和文件使用的是 glob 规则:

npx stylelint --cache **/*.{html,vue,css,sass,scss} --fix

--cache 选项可以指定使用缓存,默认生成的 .stylelintcache 文件放置于执行目录中, --fix 选项可以指定 stylelint 自动修复不符合可修复规则的代码,其他更多选项可以参考官方文档。

但需要注意有一个问题,在没有配置使用 stylelint-scss 之类的插件前, stylelint 是不能直接解析 vue 文件、 html 文件等的,会报出一堆错误:

1:1  ✖  Unknown word   CssSyntaxError

我们可以用内置的自定义语法 postcss-html 来解析(不需安装):

npx stylelint **/*.{html,vue} --custom-syntax postcss-html

也可以用内置的 scss 语法支持来解析 css 文件:

npx stylelint **/*.{css,sass,scss} --syntax scss

通过 npm 命令运行

在 scripts 中加一下就好了,对于 9102 年的前端程序员应该都是基本操作:

// package.json
{
"scripts": {
"lint:style": "stylelint **/*.{html,vue} --custom-syntax postcss-html",
"lint:css": "stylelint **/*.{css,sass,scss} --syntax scss"
}
}

或者(配置了 stylelint-scss 插件后):

{
"scripts": {
"lint:css": "stylelint **/*.{html,vue,css,sass,scss}"
}
}

然后可以手动在命令行运行:

npm run lint:css
npm run lint:css -- --fix
npm run lint:css -- --cache --fix

通过 webpack 插件运行

// webpack.conf.js
const StyleLintPlugin = require('stylelint-webpack-plugin'); module.exports = {
...
'plugins': [
...
new StyleLintPlugin({
'files': ['**/*.{html,vue,css,sass,scss}'],
'fix': false,
'cache': true,
'emitErrors': true,
'failOnError': false
})
]
};

stylelint 支持的所有命令行选项都可以在初始化插件时传递 options 来指定,包括上文提到的 --syntax 等。更多可以参考 stylelint-webpack-plugin 官方文档。

编写配置

配置对象

stylelint 支持 cosmiconfig 的配置方式,按如下顺序查找配置对象:

  • package.json 中的 stylelint 属性
  • JSON / YAML / JS 格式的 .stylelintrc 文件(可带后缀)
  • 导出 JS 对象的 stylelint.config.js 文件

它的配置也非常简单,只有 rulesextendspluginsprocessorsignoreFilesdefaultSeverity

其中 defaultSeverity 只支持 "warning""error" 两种,用于定义全局默认的报错等级。但是它没有相应的 cli 选项,实际上不太好用——比如你想 stylelint-webpack-plugin 只是警告,而 git-hooks 则是直接报错不允许提交的时候。文档上关于如何对规则单独配置错误等级有一句话提到了如何去控制:

Different reporters may use these severity levels in different way, e.g. display them differently, or exit the process differently.

但是却没有在其他地方或者 Developer guide 中找到任何与 reporters 有关的信息,有可能是需要自己写一个 formatter 。

一个简单的配置示例:

// stylelint.config.js
module.exports = {
'defaultSeverity': 'error',
'extends': [ 'stylelint-config-standard' ],
'plugins': [ 'stylelint-scss' ],
'rules': {
// 不要使用已被 autoprefixer 支持的浏览器前缀
'media-feature-name-no-vendor-prefix': true,
'at-rule-no-vendor-prefix': true,
'selector-no-vendor-prefix': true,
'property-no-vendor-prefix': true,
'value-no-vendor-prefix': true
}
};

由于可以用 stylelint-scss 去解析文件中的 scss 代码,我们暂时不需要使用官方列出的任何 processors

忽略文件

虽然可以通过配置 ignoreFiles 来简单实现,但是我们可能期望在一些遗留的老旧代码上先暂时不启用 stylelint ,等后续再慢慢放开,这样的话需要配置的文件路径就有点多了。为了方便我们可以再编写一个 .stylelintignore 文件,它的语法是跟 .gitignore.eslintignore 一样的:

# .stylelintignore
# 旧的不需打包的样式库
*.min.css # 其他类型文件
*.js
*.jpg
*.woff # 测试和打包目录
/test/
/dist/ # 通过反取忽略目录
/src/component/*
!/src/component/CompA
!/src/component/CompB
# 这样的效果是除 CompA 和 CompB 外其他目录都会被忽略

更多可以参考 node-ignore

stylelint 与 eslint 同时使用 git-hooks 配置

如果项目中已经在用 husky 的 pre-commit 钩子来运行 eslint ,现在要加 stylelint 其实很简单:

// package.json
{
...
"lint-staged": {
"*.{vue,js}": [
"eslint --fix",
"git add"
],
"*.{html,vue,css,sass,scss}": [
"stylelint --fix",
"git add",
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
}
}
}

唯一需要注意的是, lint-staged 默认是并行运行的,同时对 .vue 文件做 git add 会不会有冲突?暂时未在网上见相关讨论,我自己运行也没有任何问题,如果实在担心的话,可以将 glob 匹配分开定义。

局部禁用规则

也是跟 eslint 类似的,我们可以通过 stylelint-disable 注释来局部禁用某一项规则。

<style>
/* stylelint-disable selector-no-vendor-prefix, property-no-vendor-prefix, value-no-vendor-prefix */
.classA {
-webkit-transition-property: -webkit-transform;
transition-property: -webkit-transform;
-o-transition-property: transform;
/* stylelint-disable declaration-block-no-duplicate-properties */
transition-property: transform;
transition-property: transform, -webkit-transform;
/* stylelint-enable */
}
</style>

但是随之而来的是一个常见错误:你在文件头部忽略了对浏览器前缀的提示,却在另一个遥远的地方由于暂时性允许同名属性,通过 /* stylelint-enable */ 把之前所有忽略的规则都重新开启了。所以一定要注意,只 enable 对应的规则,形成呼应:

<style>
.classA {
/* stylelint-disable declaration-block-no-duplicate-properties */
transition-property: transform;
transition-property: transform, -webkit-transform;
/* stylelint-enable declaration-block-no-duplicate-properties */
}
</style>

其他注意事项

  1. 解析 .vue 文件(单文件组件)时请勿使用 processors

    网上一些过时的教程包括 github 上的讨论都推荐使用 stylelint-processor-html 或者 @mapbox/stylelint-processor-arbitrary-tags 来解析 html 或 vue 中的 css ,这本身并没有什么问题,但是这个插件有个 bug ,当指定 stylelint 的 --fix 后将会把 vue 文件中 <style>...</style> 以外的部分删掉。

    我们使用自定义语法 postcss-html 或者保留 stylelint-scss 插件就足够了。

  2. 一些规则在跑 --fix 选项时是有 bug 的

    比如 declaration-block-semicolon-newline-after 设置 "always" 时,不允许多条 css 规则写在一行,但自动修复后可能会出现缩进不正确:

    <style>
    .classA {
    display: block;
    } a { color: pink; top: 0; }
    </style>

    修复后(示例,之前配置时没尝试去找必现路径):

    <style>
    .classA {
    display: block;
    } a {
    color: pink;
    top: 0;
    }
    </style>

    如果你也出现这种情况,可以再指定 indentation 规则的基准缩进( baseIndentLevel ):

    module.exports = {
    ...
    rules: {
    ...
    'indentation': [2, {
    'baseIndentLevel': 1,
    }],
    'declaration-block-semicolon-newline-after': 'always'
    }
    };

参考链接

  1. Prettier + Stylelint: Writing Very Clean CSS (Or, Keeping Clean Code is a Two-Tool Game)
  2. 如何在Vue+Webpack下配置Stylelint - 简书
  3. vue单文件组件lint error自动fix及styleLint报错自动fix - segmentfault
  4. Stylelint in .vue - 掘金

本文基于 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 发布,欢迎引用、转载或演绎,但是必须保留本文的署名 BlackStorm 以及本文链接 http://www.cnblogs.com/BlackStorm/p/add-stylelint-to-your-vue-project.html ,且未经许可不能用于商业目的。如有疑问或授权协商请与我联系

如何为你的 Vue 项目添加配置 Stylelint的更多相关文章

  1. 为 VUE 项目添加 PWA 解决发布后刷新报错问题

    为什么要给 VUE 项目添加 PWA 为什么要添加?因为不管是部署在 IIS,还是 nginx,每次应用部署后,再次访问因为旧的 js 已经不存在,所以页面访问的时候会整个报错,报错的结果就是一个白屏 ...

  2. [转]Vue项目全局配置微信分享思路详解

    这篇文章给大家介绍了vue项目全局配置微信分享思路讲解,使用vue作为框架,使用vux作为ui组件库,具体内容详情大家跟随脚本之家小编一起学习吧 这个项目为移动端项目,主要用于接入公众号服务.项目采用 ...

  3. Vue项目添加动态浏览器头部title

    0. 直接上 预览链接 + 效果图 Vue项目添加动态浏览器头部title 1. 实现思路 ( 1 ) 从路由router里面得到组件的title ( 2 ) title存vuex (本项目已经封装h ...

  4. 前端单元测试,以及给现有的vue项目添加jest + Vue Test Utils的配置

    文章原址:https://www.cnblogs.com/yalong/p/11714393.html 背景介绍: 以前写的公共组件,后来需要添加一些功能,添加了好几次,每次修改我都要测试好几遍保证以 ...

  5. Vue 项目添加单元测试发现的问题及解决

    用 Jest 测试单文件组件 1.安装 Jest 和 Vue Test Utils npm install --save-dev jest @vue/test-utils 2.配置 package.j ...

  6. webpack构建vue项目(配置篇)

    最近公司要求用vue重构项目,还涉及到模块化开发,于是乎,我专门花了几天的时间研究了一下webpack这个目前来看比较热门的模块加载兼打包工具,发现上手并不是很容易,现将总结的一些有关配置的心得分享出 ...

  7. vue项目eslint配置 以及 解释

    // https://eslint.org/docs/user-guide/configuring module.exports = { root: true, parserOptions: { pa ...

  8. vue项目中配置favicon图标

    如上图所示,页面顶部的小图标会让页面显得高大上,一般把这种图标叫做favicon图标.利用vue-cli脚手架搭建的项目,如果不手动配置,页面中是不会显示favicon图标. 不配置是这样子的: fa ...

  9. 在vue项目中配置webpack

    首先我们来看一下使用Vue-cli2与Vue-cli2之后的版本(这里以Vue-cli4版本为例)创建项目目录结构的不同: Vue-cli2(左图)与Vue-cli4(右图)创建项目的目录 从上图可以 ...

随机推荐

  1. 《http权威指南》读书笔记15

    概述 最近对http很感兴趣,于是开始看<http权威指南>.别人都说这本书有点老了,而且内容太多.我个人觉得这本书写的太好了,非常长知识,让你知道关于http的很多概念,不仅告诉你怎么做 ...

  2. 初识vw和vh

     最近在项目里突然看到了一行css代码,height:100vh; 一时间有点蒙蔽 因为之前有听过这个css3新增单位,但没有去了解过. 那这个单位又跟px,rem,em,%有什么不同呢? 简述:   ...

  3. Kali学习笔记40:SQL手工注入(2)

    上一篇讲到可以通过注入得到数据库中所有的表信息 而SQL注入能不能做数据库之外的事情呢? 读取文件: ' union select null,load_file('/etc/passwd') -- 为 ...

  4. SpringMVC框架五:图片上传与JSON交互

    在正式图片上传之前,先处理一个细节问题: 每一次发布项目,Tomcat都会重新解压war包,之前上传过的图片会丢失 为了解决这个问题:可以不在Tomcat下保存图片,而是另找一个目录. 上传图片: & ...

  5. audacity 做音频分析之--初相识

    软件介绍: Audacity是一个跨平台的声音编辑软件,用于录音和编辑音频,是自由.开放源代码的软件.可在Mac OS X.Microsoft Windows.GNU/Linux和其它操作系统上运作. ...

  6. 机器学习入门01 - 框架处理(Framing)

    原文链接:https://developers.google.com/machine-learning/crash-course/framing (监督式)机器学习的定义:机器学习系统通过学习如何组合 ...

  7. 微信小程序开发-第一弹

    前言:       本篇文章为大家详细介绍微信小程序开发第一篇,后续步骤会逐步更新,欢迎大家关注. 第一步  注册        1.1 打开网址 https://mp.weixin.qq.com/  ...

  8. ASCII码字符串普通加密解密-android

    //android后台Java //ASCII加密 String str = e.getText().toString(); StringBuilder s = new StringBuilder() ...

  9. mysql服务器架构

    mysql是最广泛使用的开源数据库之一,作为后端开发人员,或多或少都会和mysql打交道,本篇文章会从sql查询语句的执行过程,来介绍mysql的服务器架构, 查询的过程大致分为从客户端到服务器,在服 ...

  10. python列表类型

    列表类型简介 列表类型是一个容器,它里面可以存放任意数量.任意类型的数据. 例如下面的几个列表中,有存储数值的.字符串的.内嵌列表的.不仅如此,还可以存储其他任意类型. >>> L ...