如何为你的 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. table-layout引起的探索——fixed和auto的区别

    问题:最近想把mui提供的底部导航组件样式单独抽出来,遇到一个问题:给底部图片下的文字设置了超出隐藏,但没有生效,如下图: 注:该底部导航为mui提供的组件 解决:这让我百思不得其解,经过一些琢磨后发 ...

  2. Python BeautifulSoup 使用

    BS4库简单使用: 1.最好配合LXML库,下载:pip install lxml 2.最好配合Requests库,下载:pip install requests 3.下载bs4:pip instal ...

  3. Android--多线程之图文混排

    前言 本周一直在说Android多线程的那些事儿,本篇博客聊一聊Android开发中一个比较经典的案例,网络数据图文混排,本片博客的案例只涉及关于开启多线程访问网络数据,不涉及缓存的内容.众所周知,从 ...

  4. 全网最全最详细的Windows下安装Anaconda2 / Anaconda3(图文详解)

    不多说,直接上干货! 说明: Anaconda2-5.0.0-Windows-x86_64.exe安装下来,默认的Python2.7 Anaconda3-4.2.0-Windows-x86_64.ex ...

  5. 绑定Github上的个人博客到Godaddy域名

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  6. redis学习总结-redis作为MyBatis的自定义缓存

    1.RedisCache.java package com.houtai.cache; import java.util.concurrent.locks.ReadWriteLock; import ...

  7. MySQL索引的概念

    索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度. 索引分为聚簇索 ...

  8. linux命令-awk入门

    最近经常查看nginx日志,有时候需要做一些统计分析,于是就想起了awk,学习了就顺便做一个记录. 目录 概述:简单介绍awk背景原理 基本用法:常用到的awk语法 内建变量 综合实例 概述 awk是 ...

  9. 一篇文章带你看懂AWS re:Invent 2018大会,揭秘Amazon Aurora

    本文由云+社区发表 | 本文作者: 刘峰,腾讯云NewSQL数据库产品负责人.曾职于联想研究院,Teradata北京研发中心,从事数据库相关工作8年.2017年加入腾讯数据库产品中心,担任NewSQL ...

  10. Linux常用命令之压缩和解压缩命令

    目录 1.压缩解压缩格式 .gz 一.将文件压缩为 .gz 格式,只能压缩文件:gzip 二.将 .gz 文件解压:gunzip 2.压缩解压缩格式 .tar.gz 一.将文件或目录压缩为 .tar. ...