使用stylelint對CSS/Sass做代碼審查


對樣式審查?很少人會這么做吧,但實際上開發者應該有這樣的態度,尤其是不同團隊多人開發時,這一點尤為重要。

在本文中,我將陳述兩點:一是為什么我們需要對樣式進行審查,二是如何將審查工具融合到整體的構建流程中(適用於 CSS,也適用於 Sass)。

簡介

什么是代碼審查

代碼審查是一個檢查代碼是否符合編程規范以及查找代碼錯誤的過程,如果要做個比喻,那么它就是編程語言的拼寫檢查工具。代碼審查可以幫助獨立開發者更好的維護代碼,但它更大的能力是幫助團隊維護代碼。

為什么我們需要審查樣式

對樣式進行審查的原因有很多,比如它可以維護代碼的一致性,解析代碼中的錯誤,減少冗余代碼等等。

下面讓我們看幾個示例:

.no-space-after-colon { display:block; } ⬆ .no-semicolon { position: relative ⬅ } 

代碼審查工具可以有效指出上述代碼中的不規范之處。在審查工具中規定代碼的規范寫法雖然不是必要的,但這種做法有助於維護代碼的一致性。此外,在團體開發中彼此不熟悉,如果我看到上述的代碼會感到很惱火。

.invalid-hex { color: #FFF00G; } ⬆ 

代碼審查工具也可以指出無效的顏色值,拋出一個類型錯誤。如果疏漏了這種錯誤,往往會導致頁面上嚴重的視覺錯誤。

.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 。

代碼審查是不是很有用呢?如果這還不夠打動你,請繼續閱讀。

stylelint 簡介

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

首先,讓我們先來審查 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,讓我們來修改一下吧。

如何審查 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,那么就請繼續閱讀后續內容

擴展 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/ 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM