如何为你的 Vue 项目添加配置 Stylelint
如今已是 9102 年了,网上许多教程和分享帖都已通过期,照着他们的步骤来会踩一些坑,如 stylelint-processor-html
已经再也不维护,以及 --fix
以后 .vue
文件只剩下 <style>
部分等。我在踩完坑跑通出满意的效果后,维护一份新的指引,以备后续项目使用,顺便分享一下。css
为何选择用 stylelint ?
这个问题有两层含义,一是为何要使用这个样式代码风格检查工具,二是与其余工具相比,为何选择 stylelint 而不是其余如 stylefmt 等。html
使用 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 }
这段代码从我我的风格来看存在很多问题:vue
- 不推荐使用 id 选择器来定义样式;
- 多重选择器(multiple selectors)没有换行,不清晰直观;
- 多个 css 规则没有换行,挤在单行太长;
- 使用了
-webkit-
前缀,可是项目中已经支持autoprefixer
; - 属性和值之间的空格时有时无等。
固然代码风格因人而异,因此才须要团队统一。在一些早期缺少完善的代码评审等制度的项目中,很容易因为程序员的偷懒图方便或在一时的紧急粗糙赶工中积累下一坨对团队其余成员不太友好、可阅读性低、较难维护的 css 。node
同类工具比较
至于第二个问题,选择 stylelint 的缘由也很简单,它是当前全部同类工具中使用人数最多的,社区较为活跃,仍在持续维护。并且正如这个 issue 中提到,当下不少大厂都在使用,如 github 的 primer 体系就定制了一套本身的规则 stylelint-config-primer
。webpack
至于 stylefmt 也曾经被推荐与 stylelint 搭配组合,很多博文都有提到。可是官方已经不推荐继续使用,直接用 stylelint 的 --fix
选项便可。git
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.github
而没有考虑 prettier 的缘由则是它但愿提供一套官方本身承认的统一风格规范,而不只仅是个 linter 或者 formatter ,可配置项不多,定制自由度较低,不适合想要本身搞事情的团队,更适合我的开发者去使用。web
如何开始使用
安装依赖
其实官方的 User guide 已经很全面,与 eslint 是很是类似的。
-
安装 stylelint
npm i -D stylelint stylelint-config-stand
后者
stylelint-config-stand
不是必需的,也能够本身根据文档从零开始配置规则,或者用第三方如 github 的规则stylelint-config-primer
。 -
安装适配预处理语法的插件
以 sass 为例:
npm i -D stylelint-scss
不过 stylus 目前没有发现可用性高的相关插件,也致使 stylelint 不能解析 stylus 语法。
-
安装 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
文件
它的配置也很是简单,只有 rules
、 extends
、 plugins
、 processors
、 ignoreFiles
和 defaultSeverity
。
其中 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>
其余注意事项
-
解析
.vue
文件(单文件组件)时请勿使用 processors网上一些过期的教程包括 github 上的讨论都推荐使用
stylelint-processor-html
或者@mapbox/stylelint-processor-arbitrary-tags
来解析 html 或 vue 中的 css ,这自己并无什么问题,可是这个插件有个 bug ,当指定 stylelint 的--fix
后将会把 vue 文件中<style>...</style>
之外的部分删掉。咱们使用自定义语法
postcss-html
或者保留stylelint-scss
插件就足够了。 -
一些规则在跑
--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' } };
参考连接
- Prettier + Stylelint: Writing Very Clean CSS (Or, Keeping Clean Code is a Two-Tool Game)
- 如何在Vue+Webpack下配置Stylelint - 简书
- vue单文件组件lint error自动fix及styleLint报错自动fix - segmentfault
- Stylelint in .vue - 掘金
<br/><br/>
<p>本文基于 <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="license"><img style="border-width: 0;" src="http://files.cnblogs.com/files/BlackStorm/by-nc-sa_4.0_88x31.gif" alt="知识共享许可协议" />知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议</a> 发布,欢迎引用、转载或演绎,可是必须保留本文的署名 <a title="BlackStorm" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="license">BlackStorm</a> 以及本文连接 <a href="http://www.cnblogs.com/BlackStorm/p/add-stylelint-to-your-vue-project.html">http://www.cnblogs.com/BlackStorm/p/add-stylelint-to-your-vue-project.html</a> ,且未经许可不能用于商业目的。若有疑问或受权协商请<a href="mailto:hsxfjames@gogobst.com" target="_blank">与我联系</a>。</p>