如何爲你的 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>