在團(tuán)隊(duì)協(xié)作開發(fā)項(xiàng)目的時(shí)候赞厕,我們會必不可少的需要寫一些 css 樣式表耙册。css 雖然不算嚴(yán)格的編程語言荧飞,但它在前端開發(fā)體系中卻占據(jù)著重要地位掌呜。css 樣式表若是寫的混亂沒有規(guī)則滓玖,那么對于團(tuán)隊(duì)其他成員或后來者或維護(hù)者一定是一個(gè)令人頭痛的問題,尤其是具有代碼強(qiáng)迫癥的人群质蕉。因此寫出一手漂亮的势篡,有規(guī)則的 css 樣式表就顯得極為重要。
我們知道在?React 項(xiàng)目中引入 TSLint 做代碼規(guī)范 這篇文章中介紹了如何使用?TSLint 做代碼規(guī)范模暗,但 TSLint 并不能對樣式表起到代碼規(guī)范作用殊霞。那么在團(tuán)隊(duì)協(xié)作時(shí)如何才能寫出統(tǒng)一的規(guī)范化的樣式表呢?我們知道?Stylelint?是一個(gè)強(qiáng)大的汰蓉、現(xiàn)代化的 CSS 檢測工具,它通過定義一系列的編碼風(fēng)格規(guī)則幫助我們避免在樣式表中出現(xiàn)錯(cuò)誤.棒卷。本篇文章所要介紹的就是如何在項(xiàng)目中引入?Stylelint?顾孽。
注意:本篇文章以?Create React App?項(xiàng)目為例,至于如何創(chuàng)建一個(gè)?Create React App?項(xiàng)目請查看?React 項(xiàng)目中引入 TSLint 做代碼規(guī)范?這篇文章中的步驟1比规。
步驟1:通過命令安裝 stylelint若厚、stylelint-order、stylelint-scss 安裝包
a蜒什、安裝 stylelint:npm install stylelint --save-dev?
b测秸、安裝 stylelint-order:npm install stylelint-order --save-dev
c、安裝 stylelint-scss:npm install stylelint-scss?--save-dev?
注意1:a 中通過命令安裝的?stylelint 是使用?Stylelint 做樣式表代碼規(guī)范所需要的一個(gè)安裝包? -----?必須安裝
注意2:b 中通過命令安裝的?stylelint-order 是用來指定樣式排序,比如聲明的塊內(nèi)(插件包)屬性的順序霎冯,例如:先寫定位铃拇,再寫盒模型,再寫內(nèi)容區(qū)樣式沈撞,最后寫 CSS3 相關(guān)屬性?----?推薦安裝
注意3慷荔、c 中通過命令安裝的?stylelint-scss 是用來執(zhí)行各種各樣的 SCSS 語法特性檢測規(guī)則(插件包) ----?如果是寫sass樣式表,必須安裝缠俺,否則不用安裝
注意4显晶、除了 b 和 c 這兩個(gè)插件包,你還可以 點(diǎn)擊此處 選擇其他你需要的插件包
步驟2:在項(xiàng)目根目錄中創(chuàng)建 stylelint.config.js 配置文件
步驟3壹士、根據(jù) 配置 | Configuration 中配置?stylelint.config.js 文件中的配置項(xiàng)
stylelint.config.js 文件中是一個(gè)大的 json 對象磷雇,其中的配置項(xiàng)有:
配置項(xiàng)?rules:規(guī)則決定檢測器要查找什么和要解決什么
配置項(xiàng)?extends:的值是個(gè)“定位器” (或 “定位器” 數(shù)組),也是最終被 require() 的躏救,因此唯笙,可以使用 Node 的 require.resolve() 算法適應(yīng)任何格式
配置項(xiàng)?plugins:插件是由社區(qū)創(chuàng)建的規(guī)則或規(guī)則集,支持方法論落剪、工具集睁本,非標(biāo)準(zhǔn) 的 CSS 特性,或非常特定的用例
配置項(xiàng)?processors:Processors 是 stylelint 的鉤子函數(shù)忠怖,可以以它的方式修改代碼呢堰,也可以在它們退出時(shí)修改結(jié)果
配置項(xiàng)?ignoreFiles:提供一個(gè) glob 或 globs 數(shù)組,忽略特定的文件
步驟4凡泣、根據(jù) Rules 中的各個(gè)配置項(xiàng)進(jìn)行配置?stylelint.config.js 文件中的配置項(xiàng) rules 中的配置項(xiàng)
步驟5枉疼、?步驟4中根據(jù)?Rules?中配置的配置項(xiàng)是最基本的配置項(xiàng),此外還要在配置 scss rules 和 order rules
a鞋拟、因?yàn)樵诓襟E1中安裝了??stylelint-scss 插件骂维,所以要根據(jù) List of rules 配置相應(yīng)的 scss rules
b、因?yàn)樵诓襟E1中安裝了?stylelint-order 插件贺纲,所以要根據(jù) stylelint-order 中的 Rules?配置相應(yīng)的 order rules
步驟6:以 vscode 編輯器為例航闺,需要在 vscode 中安裝 stylelint 插件
步驟7、重啟編輯器修改樣式文件中的聲明的塊內(nèi)屬性的順序猴誊,查看是否會出現(xiàn)錯(cuò)誤警告
備注:我的項(xiàng)目中的 stylelint.config.js 文件 中的配置如下(沒有截圖潦刃,方便拷貝)
module.exports?=?{
??plugins:?[
????'stylelint-scss',
????'stylelint-order'
??],
??rules:?{
????//?Possible?errors
????'color-no-invalid-hex':?true,
????'font-family-no-missing-generic-family-keyword':?true,
????'function-calc-no-unspaced-operator':?true,
????'function-linear-gradient-no-nonstandard-direction':?true,
????'unit-no-unknown':?true,
????'property-no-unknown':?true,
????'declaration-block-no-duplicate-properties':?true,
????'declaration-block-no-shorthand-property-overrides':?true,
????'selector-pseudo-class-no-unknown':?true,
????'selector-pseudo-element-no-unknown':?[
??????true,
??????{
????????ignorePseudoElements:?['ng-deep']
??????}
????],
????'media-feature-name-no-unknown':?true,
????'comment-no-empty':?true,
????'no-duplicate-at-import-rules':?true,
????'no-duplicate-selectors':?true,
????'no-empty-source':?true,
????'no-extra-semicolons':?true,
????'no-invalid-double-slash-comments':?true,
????//?Limit?language?features
????'unit-blacklist':?[],
????'shorthand-property-no-redundant-values':?true,
????'value-no-vendor-prefix':?true,
????'property-blacklist':?[''],
????'property-no-vendor-prefix':?true,
????'declaration-block-no-redundant-longhand-properties':?true,
????'declaration-no-important':?true,
????'declaration-property-unit-blacklist':?{},
????'declaration-property-unit-whitelist':?{
??????'font-size':?['px',?'rem',?'vmin']
????},
????'declaration-property-value-whitelist':?{
??????'float':?['none']
????},
????'selector-max-compound-selectors':?4,
????'selector-max-empty-lines':?0,
????'selector-max-id':?1,
????'selector-no-vendor-prefix':?true,
????'media-feature-name-no-vendor-prefix':?true,
????'at-rule-no-vendor-prefix':?true,
????'at-rule-blacklist':?['extend'],
????//?Stylistic?issues
????'color-hex-case':?'lower',
????'color-hex-length':?'short',
????'font-family-name-quotes':?'always-where-recommended',
????'function-comma-space-after':?'always',
????'function-comma-space-before':?'never',
????'function-name-case':?'lower',
????'function-parentheses-space-inside':?'never',
????'function-url-quotes':?'never',
????'function-whitespace-after':?'always',
????'font-weight-notation':?'numeric',
????'number-leading-zero':?'always',
????'number-no-trailing-zeros':?true,
????'string-quotes':?[
??????'double',
??????{
????????'avoidEscape':?true
??????}
????],
????'length-zero-no-unit':?true,
????'unit-case':?'lower',
????'value-keyword-case':?[
??????'lower',
??????{
????????ignoreProperties:?['family']
??????}
????],
????'value-list-comma-newline-after':?'always-multi-line',
????'value-list-comma-space-after':?'always-single-line',
????'value-list-comma-space-before':?'never',
????'value-list-max-empty-lines':?0,
????'property-case':?'lower',
????'declaration-bang-space-after':?'never',
????'declaration-bang-space-before':?'always',
????'declaration-colon-space-after':?'always-single-line',
????'declaration-colon-space-before':?'never',
????'declaration-empty-line-before':?'never',
????'declaration-block-single-line-max-declarations':?1,
????'declaration-property-value-blacklist':?{
??????'/^border/':?['none']
????},
????'block-closing-brace-empty-line-before':?'never',
????'block-closing-brace-newline-before':?'always',
????'block-opening-brace-newline-after':?'always',
????'block-opening-brace-space-before':?'always',
????'selector-attribute-brackets-space-inside':?'never',
????'selector-attribute-operator-space-after':?'never',
????'selector-attribute-operator-space-before':?'never',
????'selector-attribute-quotes':?'always',
????'selector-combinator-space-after':?'always',
????'selector-combinator-space-before':?'always',
????'selector-descendant-combinator-no-non-space':?true,
????'selector-pseudo-class-case':?'lower',
????'selector-pseudo-class-parentheses-space-inside':?'never',
????'selector-pseudo-element-case':?'lower',
????'selector-pseudo-element-colon-notation':?'single',
????'selector-type-case':?'lower',
????'selector-list-comma-newline-after':?'always-multi-line',
????'selector-list-comma-space-after':?'always-single-line',
????'selector-list-comma-space-before':?'never',
????'rule-empty-line-before':?[
??????'always',
??????{
????????ignore:?['after-comment',?'first-nested']
??????}
????],
????'media-feature-colon-space-after':?'always',
????'media-feature-colon-space-before':?'never',
????'media-feature-name-case':?'lower',
????'media-feature-parentheses-space-inside':?'never',
????'media-feature-range-operator-space-after':?'always',
????'media-feature-range-operator-space-before':?'always',
????'at-rule-empty-line-before':?[
??????'always',
??????{
????????ignore:?['after-comment',?'blockless-after-same-name-blockless'],
????????except:?['first-nested'],
????????ignoreAtRules:?['else']
??????}
????],
????'at-rule-name-space-after':?'always',
????'at-rule-semicolon-space-before':?'never',
????'comment-empty-line-before':?[
??????'always',
??????{
????????except:?['first-nested']
??????}
????],
????'comment-whitespace-inside':?'always',
????indentation:?2,
????'max-empty-lines':?[
??????1,
??????{
????????ignore:?['comments']
??????}
????],
????'no-eol-whitespace':?[
??????true,
??????{
????????ignore:?['empty-lines']
??????}
????],
????//?Sass?rules
????'scss/at-else-closing-brace-newline-after':?'always-last-in-chain',
????'scss/at-else-closing-brace-space-after':?'always-intermediate',
????'scss/at-else-empty-line-before':?'never',
????'scss/at-else-if-parentheses-space-before':?'always',
????'scss/at-function-named-arguments':?'never',
????'scss/at-function-parentheses-space-before':?'always',
????'scss/at-if-closing-brace-newline-after':?'always-last-in-chain',
????'scss/at-if-closing-brace-space-after':?'always-intermediate',
????'scss/at-mixin-argumentless-call-parentheses':?'always',
????'scss/at-mixin-named-arguments':?'never',
????'scss/at-mixin-parentheses-space-before':?'always',
????'scss/at-rule-no-unknown':?true,
????'scss/dollar-variable-colon-newline-after':?'always-multi-line',
????'scss/dollar-variable-colon-space-after':?'always-single-line',
????'scss/dollar-variable-colon-space-before':?'never',
????'scss/dollar-variable-empty-line-before':?[
??????'always',
??????{
????????except:?['after-comment',?'after-dollar-variable',?'first-nested']
??????}
????],
????'scss/dollar-variable-no-missing-interpolation':?true,
????'scss/dollar-variable-pattern':?'^_?[a-z]+[\\w-]*$',
????'scss/at-extend-no-missing-placeholder':?true,
????'scss/at-import-no-partial-leading-underscore':?true,
????'scss/double-slash-comment-empty-line-before':?'always',
????'scss/double-slash-comment-whitespace-inside':?'always',
????'scss/declaration-nested-properties':?'never',
????'scss/operator-no-newline-after':?true,
????'scss/operator-no-newline-before':?true,
????//?'scss/operator-no-unspaced':?true,?//?Causing?url?parsing?error,?temporarily?disabled.
????'scss/selector-no-redundant-nesting-selector':?true,
????'scss/no-duplicate-dollar-variables':?true,
????//?Order?rules
????'order/order':?[
??????'custom-properties',
??????'dollar-variables',
??????'declarations',
??????{
????????type:?'at-rule',
????????hasBlock:?false
??????},
??????'rules',
??????{
????????type:?'at-rule',
????????hasBlock:?true
??????}
????],
????'order/properties-order':?[
??????[
????????'content',
????????'position',?'top',?'right',?'bottom',?'left',
????????'display',?'flex-flow',?'flex-direction',?'flex-wrap',?'justify-content',?'align-content',?'align-items',
????????'flex',?'flex-grow',?'flex-shrink',?'flex-basis',?'align-self',?'order',
????????'margin',?'margin-top',?'margin-right',?'margin-bottom',?'margin-left',
????????'outline',?'outline-width',?'outline-style',?'outline-color',?'outline-offset',
????????'box-shadow',?'box-sizing',
????????'border-radius',?'border-top-right-radius',?'border-bottom-right-radius',?'border-bottom-left-radius',?'border-top-left-radius',
????????'border',?'border-width',?'border-style',?'border-color',
????????'border-top',?'border-top-width',?'border-top-style',?'border-top-color',
????????'border-right',?'border-right-width',?'border-right-style',?'border-right-color',
????????'border-bottom',?'border-bottom-width',?'border-bottom-style',?'border-bottom-color',
????????'border-left',?'border-left-width',?'border-left-style',?'border-left-color',
????????'border-image',?'border-image-source',?'border-image-slice',?'border-image-width',?'border-image-outset',?'border-image-repeat',
????????'padding',?'padding-top',?'padding-right',?'padding-bottom',?'padding-left',
????????'max-width',?'max-height',?'min-width',?'min-height',?'width',?'height',
????????'background',?'background-attachment',?'background-clip',?'background-origin',?'background-size',?'background-color',?'background-image',?'background-position',?'background-repeat',
????????'table-layout',?'border-collapse',?'border-spacing',?'caption-side',?'empty-cells',
????????'font',?'font-style',?'font-variant',?'font-weight',?'font-size',?'line-height',?'font-family'
??????],
??????{
????????unspecified:?'bottom'
??????}
????]
??}
};
參考網(wǎng)址:
stylelint 英文:https://stylelint.io/? ??
stylelint 中文:https://cloud.tencent.com/developer/chapter/18030
stylelint-order:?https://github.com/hudochenkov/stylelint-order
stylelint-scss:https://github.com/kristerkari/stylelint-scss