Stylelint 是 CSS/SCSS 的靜態分析工具,用于檢查其中的違規和錯誤。
1. 環境要求
v16 以上的 Stylelint,支持 Node.js 的版本為 v18.12.0+。
在命令行工具中輸入以下內容后回車,來查看當前系統中 Node.js 的版本。
node -v
Node.js 推薦使用 v18.20.3+ 或者 v20.13.1+。
這里使用的包管理器是 PNPM,版本為 v9.1.4。
2 安裝
2.1 針對 CSS
pnpm install -D stylelint stylelint-config-standard stylelint-order
2.2 針對 SCSS(包含CSS)
pnpm install -D stylelint stylelint-order stylelint-config-standard stylelint-config-standard-scss stylelint-config-sass-guidelines stylelint-scss
3 配置
在項目根目錄下創建 stylelint.config.js 文件,根據樣式文件類型(CSS/SCSS)填入以下內容:
3.1 針對 CSS
export default {// 繼承已有配置 如果規則與自己想要的沖突 可以在下面rules中修改規則extends: ['stylelint-config-standard'],// 插件是由社區創建的規則或規則集 按照規則對CSS屬性進行排序plugins: [// 指定排序,比如聲明的塊內(插件包)屬性的順序'stylelint-order',],rules: {// 允許的最大嵌套深度為 3'max-nesting-depth': 3,// 屏蔽一些scss等語法檢查'at-rule-no-unknown': [true,{ignoreAtRules: ['extend','at-root','debug','warn','error','if','else','for','each','while','mixin','include','content','return','function',],},],// 屏蔽沒有申明通用字體'font-family-no-missing-generic-family-keyword': null,// ID選擇器 最多使用一個'selector-max-id': 1,// 不允許使用的選擇器的類型'selector-no-qualifying-type': null,// 屏蔽類選擇器的檢查,以確保使用字符 __'selector-class-pattern': null,// 允許的最大復合選擇器為 5'selector-max-compound-selectors': 5,// 屬性排序規則'order/properties-order': [['content','position','top','right','bottom','left','z-index','display','vertical-align','flex','flex-grow','flex-shrink','flex-basis','flex-direction','flex-flow','flex-wrap','grid','grid-area','grid-template','grid-template-areas','grid-template-rows','grid-template-columns','grid-row','grid-row-start','grid-row-end','grid-column','grid-column-start','grid-column-end','grid-auto-rows','grid-auto-columns','grid-auto-flow','grid-gap','grid-row-gap','grid-column-gap','gap','row-gap','column-gap','align-content','align-items','align-self','justify-content','justify-items','justify-self','order','float','clear','object-fit','overflow','overflow-x','overflow-y','overflow-scrolling','clip',//'box-sizing','width','min-width','max-width','height','min-height','max-height','margin','margin-top','margin-right','margin-bottom','margin-left','padding','padding-top','padding-right','padding-bottom','padding-left','border','border-spacing','border-collapse','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-radius','border-top-left-radius','border-top-right-radius','border-bottom-right-radius','border-bottom-left-radius','border-image','border-image-source','border-image-slice','border-image-width','border-image-outset','border-image-repeat','border-top-image','border-right-image','border-bottom-image','border-left-image','border-corner-image','border-top-left-image','border-top-right-image','border-bottom-right-image','border-bottom-left-image',//'background','background-color','background-image','background-attachment','background-position','background-position-x','background-position-y','background-clip','background-origin','background-size','background-repeat','color','box-decoration-break','box-shadow','outline','outline-width','outline-style','outline-color','outline-offset','table-layout','caption-side','empty-cells','list-style','list-style-position','list-style-type','list-style-image',//'font','font-weight','font-style','font-variant','font-size-adjust','font-stretch','font-size','font-family','src','line-height','letter-spacing','quotes','counter-increment','counter-reset','-ms-writing-mode','text-align','text-align-last','text-decoration','text-emphasis','text-emphasis-position','text-emphasis-style','text-emphasis-color','text-indent','text-justify','text-outline','text-transform','text-wrap','text-overflow','text-overflow-ellipsis','text-overflow-mode','text-shadow','white-space','word-spacing','word-wrap','word-break','overflow-wrap','tab-size','hyphens','interpolation-mode',//'opacity','visibility','filter','resize','cursor','pointer-events','user-select',//'unicode-bidi','direction','columns','column-span','column-width','column-count','column-fill','column-gap','column-rule','column-rule-width','column-rule-style','column-rule-color','break-before','break-inside','break-after','page-break-before','page-break-inside','page-break-after','orphans','widows','zoom','max-zoom','min-zoom','user-zoom','orientation','fill','stroke',//'transition','transition-delay','transition-timing-function','transition-duration','transition-property','transform','transform-origin','animation','animation-name','animation-duration','animation-play-state','animation-timing-function','animation-delay','animation-iteration-count','animation-direction','animation-fill-mode',],{unspecified: 'bottom',severity: 'warning',},],// 屏蔽屬性按字母順序檢查'order/properties-alphabetical-order': null,},
};
3.2 針對 SCSS
export default {// 繼承已有配置 如果規則與自己想要的沖突 可以在下面rules中修改規則extends: ['stylelint-config-standard','stylelint-config-standard-scss','stylelint-config-sass-guidelines',],// 插件是由社區創建的規則或規則集 按照規則對CSS屬性進行排序plugins: [// 執行各種各樣的 SCSS語法特性檢測規則(插件包)'stylelint-scss',// 指定排序,比如聲明的塊內(插件包)屬性的順序'stylelint-order',],rules: {// 允許的最大嵌套深度為 3'max-nesting-depth': 3,// 屏蔽一些scss等語法檢查'at-rule-no-unknown': [true,{ignoreAtRules: ['extend','at-root','debug','warn','error','if','else','for','each','while','mixin','include','content','return','function',],},],// 屏蔽沒有申明通用字體'font-family-no-missing-generic-family-keyword': null,// ID選擇器 最多使用一個'selector-max-id': 1,// 不允許使用的選擇器的類型'selector-no-qualifying-type': null,// 屏蔽類選擇器的檢查,以確保使用字符 __'selector-class-pattern': null,// 允許的最大復合選擇器為 5'selector-max-compound-selectors': 5,// 屬性排序規則'order/properties-order': [['content','position','top','right','bottom','left','z-index','display','vertical-align','flex','flex-grow','flex-shrink','flex-basis','flex-direction','flex-flow','flex-wrap','grid','grid-area','grid-template','grid-template-areas','grid-template-rows','grid-template-columns','grid-row','grid-row-start','grid-row-end','grid-column','grid-column-start','grid-column-end','grid-auto-rows','grid-auto-columns','grid-auto-flow','grid-gap','grid-row-gap','grid-column-gap','gap','row-gap','column-gap','align-content','align-items','align-self','justify-content','justify-items','justify-self','order','float','clear','object-fit','overflow','overflow-x','overflow-y','overflow-scrolling','clip',//'box-sizing','width','min-width','max-width','height','min-height','max-height','margin','margin-top','margin-right','margin-bottom','margin-left','padding','padding-top','padding-right','padding-bottom','padding-left','border','border-spacing','border-collapse','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-radius','border-top-left-radius','border-top-right-radius','border-bottom-right-radius','border-bottom-left-radius','border-image','border-image-source','border-image-slice','border-image-width','border-image-outset','border-image-repeat','border-top-image','border-right-image','border-bottom-image','border-left-image','border-corner-image','border-top-left-image','border-top-right-image','border-bottom-right-image','border-bottom-left-image',//'background','background-color','background-image','background-attachment','background-position','background-position-x','background-position-y','background-clip','background-origin','background-size','background-repeat','color','box-decoration-break','box-shadow','outline','outline-width','outline-style','outline-color','outline-offset','table-layout','caption-side','empty-cells','list-style','list-style-position','list-style-type','list-style-image',//'font','font-weight','font-style','font-variant','font-size-adjust','font-stretch','font-size','font-family','src','line-height','letter-spacing','quotes','counter-increment','counter-reset','-ms-writing-mode','text-align','text-align-last','text-decoration','text-emphasis','text-emphasis-position','text-emphasis-style','text-emphasis-color','text-indent','text-justify','text-outline','text-transform','text-wrap','text-overflow','text-overflow-ellipsis','text-overflow-mode','text-shadow','white-space','word-spacing','word-wrap','word-break','overflow-wrap','tab-size','hyphens','interpolation-mode',//'opacity','visibility','filter','resize','cursor','pointer-events','user-select',//'unicode-bidi','direction','columns','column-span','column-width','column-count','column-fill','column-gap','column-rule','column-rule-width','column-rule-style','column-rule-color','break-before','break-inside','break-after','page-break-before','page-break-inside','page-break-after','orphans','widows','zoom','max-zoom','min-zoom','user-zoom','orientation','fill','stroke',//'transition','transition-delay','transition-timing-function','transition-duration','transition-property','transform','transform-origin','animation','animation-name','animation-duration','animation-play-state','animation-timing-function','animation-delay','animation-iteration-count','animation-direction','animation-fill-mode',],{unspecified: 'bottom',severity: 'warning',},],// 屏蔽屬性按字母順序檢查'order/properties-alphabetical-order': null,},
};
4 結合 Husky
利用 Husky 在 git commit 時自動校驗文件中的樣式內容,如不符合規范,則文件不能被 commit。詳細操作見《前端工程化工具系列(五)—— Husky(v9.0.11)&lint-staged(v15.2.5):代碼提交前的自動審查利器》中的 2.1節。
5 結合 VS Code
配合 VS Code 插件,可在做文件保存時自動修復錯誤。詳細操作見《前端工程化工具系列(六)—— VS Code(v1.89.1):強大的代碼編輯器》。