对样式审查?不多人会这么作吧,但实际上开发者应该有这样的态度,尤为是不一样团队多人开发时,这一点尤其重要。php
在本文中,我将陈述两点:一是为何咱们须要对样式进行审查,二是如何将审查工具融合到总体的构建流程中(适用于 CSS,也适用于 Sass)。css
代码审查是一个检查代码是否符合编程规范以及查找代码错误的过程,若是要作个比喻,那么它就是编程语言的拼写检查工具。代码审查能够帮助独立开发者更好的维护代码,但它更大的能力是帮助团队维护代码。git
对样式进行审查的缘由有不少,好比它能够维护代码的一致性,解析代码中的错误,减小冗余代码等等。github
下面让咱们看几个示例:web
.no-space-after-colon { display:block; } ⬆ .no-semicolon { position: relative ⬅ }
代码审查工具能够有效指出上述代码中的不规范之处。在审查工具中规定代码的规范写法虽然不是必要的,但这种作法有助于维护代码的一致性。此外,在团体开发中彼此不熟悉,若是我看到上述的代码会感到很恼火。sql
.invalid-hex { color: #FFF00G; } ⬆
代码审查工具也能够指出无效的颜色值,抛出一个类型错误。若是疏漏了这种错误,每每会致使页面上严重的视觉错误。npm
.unnecessary-prefixes { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }
随着浏览器的升级换代,有一些 CSS3 属性的浏览器前缀已经没有意义了。代码审查工具能够指出这些无心义前缀,此外,将它和 Autoprefixer 搭配起来,能够更加有效。编程
.duplicate-rule { display: block; transition: opacity .2s; color: #444; background-color: #eee; transition: background-color .4s; ⬅ }
样式重复是一个常见的错误,就上面的代码而言,这里的 transition
值究竟是 opacity
仍是 background-color
呢?显而易见, background-color
会替代 opacity
。gulp
代码审查是否是颇有用呢?若是这还不够打动你,请继续阅读。浏览器
stylelint 是一个基于 Javascript 的代码审查工具,它易于扩展,支持最新的 CSS 语法,也理解相似 CSS 的语法。此外,由于它是基于 JavaScript,因此比起 Ruby 开发的 scss-lint 速度更快。
stylelint 是一个强大和现代的 CSS 审查工具,有助于开发者推行统一的代码规范,避免样式错误。
stylelint 由PostCSS 提供技术支持,因此它也能够理解 PostCSS 解析的语法,好比 SCSS。
PostCSS 是一个使用 JS 解析样式的插件集合,它能够用来审查 CSS 代码,也能够加强 CSS 的语法(好比变量和混合宏),还支持将来的 CSS 语法、行内图片等等。
PostCSS 的哲学是专一于处理一件事,并作到极致,目前它已经有了 200 多个插件,因为它们都是基于 JavaScript 编写的,因此运行速度很是快。
PostCSS 和 stylelint 就是咱们接下来将要介绍的代码审查工具。
stylelint 的强大之处就在于它很是灵活,无需花费过多的时间过滤各类规则,只需配置须要的规则便可完成 stylelint 的初始化。 stylelint 的配置文档 很是适用于初学者了解相关的审查规则。此外,他们还提供了一份 标准配置文件 用做参考。
在本文中,我将带领你们从一份更友好、简洁的配置开始。就我我的而言,我认为它比官方提供的配置文件更加灵活:
"rules": { "block-no-empty": true, "color-no-invalid-hex": true, "declaration-colon-space-after": "always", "declaration-colon-space-before": "never", "function-comma-space-after": "always", "function-url-quotes": "double", "media-feature-colon-space-after": "always", "media-feature-colon-space-before": "never", "media-feature-name-no-vendor-prefix": true, "max-empty-lines": 5, "number-leading-zero": "never", "number-no-trailing-zeros": true, "property-no-vendor-prefix": true, "rule-no-duplicate-properties": true, "declaration-block-no-single-line": true, "rule-trailing-semicolon": "always", "selector-list-comma-space-before": "never", "selector-list-comma-newline-after": "always", "selector-no-id": true, "string-quotes": "double", "value-no-vendor-prefix": true }
最后,建议读一下 stylelint 的官方配置文档 ,在其基础上作一些个性化的设置。接下来,让咱们将这些审查规则融入到构建流程中。
首先,让咱们先来审查 CSS 代码。配置审查工具的过程很是简单,你只须要安装 gulp-postcss
/ postcss-reporter
和 stylelint
便可:
npm install gulp-postcss postcss-reporter stylelint --save-dev
接下来是 gulp 的配置文件 gulpfile.js
:
/** * Linting CSS stylesheets with Stylelint * http://www.creativenightly.com/2016/02/How-to-lint-your-css-with-stylelint/ */ var gulp = require('gulp'); var postcss = require('gulp-postcss'); var reporter = require('postcss-reporter'); var stylelint = require('stylelint'); gulp.task("css-lint", function() { // Stylelint config rules var stylelintConfig = { "rules": { "block-no-empty": true, "color-no-invalid-hex": true, "declaration-colon-space-after": "always", "declaration-colon-space-before": "never", "function-comma-space-after": "always", "function-url-quotes": "double", "media-feature-colon-space-after": "always", "media-feature-colon-space-before": "never", "media-feature-name-no-vendor-prefix": true, "max-empty-lines": 5, "number-leading-zero": "never", "number-no-trailing-zeros": true, "property-no-vendor-prefix": true, "rule-no-duplicate-properties": true, "declaration-block-no-single-line": true, "rule-trailing-semicolon": "always", "selector-list-comma-space-before": "never", "selector-list-comma-newline-after": "always", "selector-no-id": true, "string-quotes": "double", "value-no-vendor-prefix": true } } var processors = [ stylelint(stylelintConfig), // Pretty reporting config reporter({ clearMessages: true, throwError: true }) ]; return gulp.src( // Stylesheet source: ['app/assets/css/**/*.css', // Ignore linting vendor assets: // (Useful if you have bower components) '!app/assets/css/vendor/**/*.css'] ) .pipe(postcss(processors)); });
上面短短五十行代码包含了审查规则和文件路径,请确保资源路径与上面的代码相匹配。
更使人惊奇的是,只需改动一小段代码就能够同时支持 Sass,让咱们来修改一下吧。
使用 PostCSS 审查 Sass 代码很是简单,与审查 CSS 代码惟一不一样的地方就在于,你须要让 PostCSS 识别 .scss
语法。这一问题能够经过安装 postcss-scss
插件来完成,安装插件后,修改一下配置文件:
npm install postcss-scss --save-dev
修改配置文件:
//[...] return gulp.src( ['app/assets/css/**/*.css', '!app/assets/css/vendor/**/*.css'] ) .pipe(postcss(processors), {syntax: syntax_scss}); ⬅ });
以上就是 gulp 配置文件的所有内容了。总结起来,你须要安装如下工具:
npm install gulp-postcss postcss-reporter stylelint postcss-scss --save-dev
/** * Linting Sass stylesheets with Stylelint * http://www.creativenightly.com/2016/02/How-to-lint-your-css-with-stylelint/ */ var gulp = require('gulp'); var postcss = require('gulp-postcss'); var reporter = require('postcss-reporter'); var syntax_scss = require('postcss-scss'); var stylelint = require('stylelint'); gulp.task("scss-lint", function() { // Stylelint config rules var stylelintConfig = { "rules": { "block-no-empty": true, "color-no-invalid-hex": true, "declaration-colon-space-after": "always", "declaration-colon-space-before": "never", "function-comma-space-after": "always", "function-url-quotes": "double", "media-feature-colon-space-after": "always", "media-feature-colon-space-before": "never", "media-feature-name-no-vendor-prefix": true, "max-empty-lines": 5, "number-leading-zero": "never", "number-no-trailing-zeros": true, "property-no-vendor-prefix": true, "rule-no-duplicate-properties": true, "declaration-block-no-single-line": true, "rule-trailing-semicolon": "always", "selector-list-comma-space-before": "never", "selector-list-comma-newline-after": "always", "selector-no-id": true, "string-quotes": "double", "value-no-vendor-prefix": true } } var processors = [ stylelint(stylelintConfig), reporter({ clearMessages: true, throwError: true }) ]; return gulp.src( ['app/assets/css/**/*.css', // Ignore linting vendor assets // Useful if you have bower components '!app/assets/css/vendor/**/*.css'] ) .pipe(postcss(processors), {syntax: syntax_scss}); });
若是你想了解如何使用插件扩展 stylelint,那么就请继续阅读后续内容
和 PostCSS 同样,Stylelint 也能够经过插件进行扩展。接下来让咱们经过一些实例学习如何使用审查工具改善代码的可读性和可维护性。
话说有个产品经理新接了个 web app 的活,项目正处于紧张的开发中,为了减小一些开发时间,他决定增长一个特性来替代以前的一揽子方案,这个特性是这样的:给组件自己添加一个鼠标悬停时的 box-shadow 效果,同时给组件的内部的连接增长一个鼠标悬停样式。
下面是这个产品经理增长的代码段:
.component { position: relative; //[...] &:hover { ⬅ box-shadow: 1px 1px 5px 0px rgba(0,0,0,0.75); .component__child { ⬅ ul { ⬅ li { ⬅ a { ⬅ &:hover { ⬅ text-decoration: underline; } } } } } } }
真是惨不忍睹!
选择器嵌套是 Sass 最容易被误用的特性,合理使用它能够提升开发效率,滥用则会毁掉整个项目。嵌套每每是由偷懒引发的,这些代码每每难以阅读。上面的 &:hover{...}
的嵌套层级太深,很容易混淆其余开发者对这段代码的理解。最重要的是,这段嵌套在这里彻底是没有必要的。
这就是上面的嵌套代码编译生成的 CSS:
.component:hover .component_child ul li a:hover {} /* What the heck is this?! */
若是后续接手项目的开发者想要覆盖这段级联样式,那真是大工程。因此有一点值得牢记,那就是除非你很是肯定嵌套是必要的,不然不要使用它。
幸运的是,咱们有插件来阻止这种状况的发生!咱们能够安装 stylelint-statement-max-nesting-depth
插件,设置最大嵌套层级来避免过渡嵌套的现象:
npm install stylelint-statement-max-nesting-depth --save-dev
在 gulp 的排位置文件中增长 scss-lint
相关的任务信息:
gulp.task("scss-lint", function() { var stylelintConfig = { "plugins": [ "stylelint-statement-max-nesting-depth" ], "rules": { //[...] "statement-max-nesting-depth": [3, { countAtRules: false }], } } //[..] });
为了加强团队的共建意识,我在这里将 limit
设置为了 3
。因为有嵌套层级的限制,因此产品经理就会来自 stylelint 的重构提示。产品经理没怎么细想,就改为了下面这样:
.component:hover { box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.75); .component__child { ul { li { a:hover { text-decoration: underline; } } } } }
这个重构以后的版本看起来可读性好多了,但仍然有很多缺陷。事实上,上面代码中的嵌套是彻底没有必要的。stylelint 能够检测出这一点,并会强制产品经理从新思考样式代码。
.component:hover { box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.75); } .component__child { a:hover { text-decoration: underline; } }
如今,代码更加健壮了!stylelint 已经接受了代码,不会再提出异议了。虽然上面的代码没有问题,但咱们其实能够作的更好。若是你但愿严格要求团队的每个成员,那么能够禁用嵌套,这会让团队成员,包括产品经理,更加严谨地编写代码。
.component:hover { box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.75); } .component__link:hover { text-decoration: underline; }
经过以上介绍和实战演练,但愿我已经说服了你:样式审查是很是值得投入的一项流程。代码审查应该成为咱们的朋友,只需投入一点时间,就能够收获代码总体的可读性、可维护性。
本文根据 @Scotty Vernon 的《 How to lint your Sass/CSS properly with Stylelint 》所译,整个译文带有咱们本身的理解与思想,若是译得很差或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://www.creativenightly.com/2016/02/How-to-lint-your-css-with-stylelint/ 。