如何為你的 Vue 項目添加配置 Stylelint

来源:https://www.cnblogs.com/BlackStorm/archive/2019/01/06/add-stylelint-to-your-vue-project.html
-Advertisement-
Play Games

如何為你的 Vue 項目添加配置 Stylelint 現在已經是 9102 年了,網上許多教程和分享帖都已經過期,照著他們的步驟來會踩一些坑,如 已經不再維護,以及 之後 文件只剩下 `` 部分等。我在踩完坑跑通出滿意的效果後,維護一份新的指引,以備後續項目使用,順便分享一下。 為什麼選擇用 sty ...


如何為你的 Vue 項目添加配置 Stylelint

現在已經是 9102 年了,網上許多教程和分享帖都已經過期,照著他們的步驟來會踩一些坑,如 stylelint-processor-html 已經不再維護,以及 --fix 之後 .vue 文件只剩下 <style> 部分等。我在踩完坑跑通出滿意的效果後,維護一份新的指引,以備後續項目使用,順便分享一下。

為什麼選擇用 stylelint ?

這個問題有兩層含義,一是為什麼要使用這個樣式代碼風格檢查工具,二是與其他工具相比,為什麼選擇 stylelint 而不是其他如 stylefmt 等。

使用 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 }

這段代碼從我個人風格來看存在不少問題:

  1. 不推薦使用 id 選擇器來定義樣式;
  2. 多重選擇器(multiple selectors)沒有換行,不清晰直觀;
  3. 多個 css 規則沒有換行,擠在單行太長;
  4. 使用了 -webkit- 首碼,但是項目中已經支持 autoprefixer
  5. 屬性和值之間的空格時有時無等。

當然代碼風格因人而異,所以才需要團隊統一。在一些早期缺乏完善的代碼評審等制度的項目中,很容易由於程式員的偷懶圖方便或在一時的緊急粗糙趕工中積累下一坨對團隊其他成員不太友好、可閱讀性低、較難維護的 css 。

同類工具比較

至於第二個問題,選擇 stylelint 的原因也很簡單,它是當前所有同類工具中使用人數最多的,社區較為活躍,仍在持續維護。而且正如這個 issue 中提到,當下很多大廠都在使用,如 github 的 primer 體系就定製了一套自己的規則 stylelint-config-primer

至於 stylefmt 也曾經被推薦與 stylelint 搭配組合,不少博文都有提到。但是官方已經不推薦繼續使用,直接用 stylelint 的 --fix 選項即可。

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.

而沒有考慮 prettier 的原因則是它希望提供一套官方自己認可的統一風格規範,而不僅僅是個 linter 或者 formatter ,可配置項很少,定製自由度較低,不適合想要自己搞事情的團隊,更適合個人開發者去使用。

如何開始使用

安裝依賴

其實官方的 User guide 已經很全面,與 eslint 是非常相似的。

  1. 安裝 stylelint

    npm i -D stylelint stylelint-config-stand

    後者 stylelint-config-stand 不是必需的,也可以自己根據文檔從零開始配置規則,或者用第三方如 github 的規則 stylelint-config-primer

  2. 安裝適配預處理語法的插件

    以 sass 為例:

    npm i -D stylelint-scss

    不過 stylus 目前沒有發現可用性高的相關插件,也導致 stylelint 不能解析 stylus 語法。

  3. 安裝 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 文件

它的配置也非常簡單,只有 rulesextendspluginsprocessorsignoreFilesdefaultSeverity

其中 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>

其他註意事項

  1. 解析 .vue 文件(單文件組件)時請勿使用 processors

    網上一些過時的教程包括 github 上的討論都推薦使用 stylelint-processor-html 或者 @mapbox/stylelint-processor-arbitrary-tags 來解析 html 或 vue 中的 css ,這本身並沒有什麼問題,但是這個插件有個 bug ,當指定 stylelint 的 --fix 後將會把 vue 文件中 <style>...</style> 以外的部分刪掉。

    我們使用自定義語法 postcss-html 或者保留 stylelint-scss 插件就足夠了。

  2. 一些規則在跑 --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'
        }
    };

參考鏈接

  1. Prettier + Stylelint: Writing Very Clean CSS (Or, Keeping Clean Code is a Two-Tool Game)
  2. 如何在Vue+Webpack下配置Stylelint - 簡書
  3. vue單文件組件lint error自動fix及styleLint報錯自動fix - segmentfault
  4. Stylelint in .vue - 掘金



本文基於 知識共用許可協議知識共用署名-非商業性使用-相同方式共用 4.0 國際許可協議 發佈,歡迎引用、轉載或演繹,但是必須保留本文的署名 BlackStorm 以及本文鏈接 http://www.cnblogs.com/BlackStorm/p/add-stylelint-to-your-vue-project.html ,且未經許可不能用於商業目的。如有疑問或授權協商請與我聯繫


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡介紹兩個 Redis 可視化工具。Redis Desktop Manager 和 treeNMS。 一、Redis Desktop Manager 下載地址:https://redisdesktop.com/download 網盤下載地址:鏈接:https://pan.baidu.com/s/1 ...
  • Hive與Hbase整合 1.文檔   Hive HBase Integration ...
  • Tasks and Operator Chains(任務及操作鏈) 在分散式環境下,Flink將操作的子任務鏈在一起組成一個任務,每一個任務在一個線程中執行。將操作鏈在一起是一個不錯的優化:它減少了線程間的切換和緩衝,提升了吞吐量同時減低了時延。這些鏈式行為是可配置的,詳情請見: " chainin ...
  • Android遠程桌面助手(B1391),支持到Android9。 ...
  • datagrid combobox輸入框非法輸入判斷與事件總結 by:授客 QQ:1033553122 測試環境 jquery-easyui-1.5.3 常見事件 onSelect // 選擇下拉列表項時觸發的事件 onHidePanel // 收起下拉列表時觸發的事件 onChange // co ...
  • 這種寫法不是對象克隆,就是把obj的記憶體地址賦給obj2 通過 for in 克隆 不管公有還是私有的都克隆成私有的。 js提供了一個克隆方法 objct.create() var obj2=object.create(obj) 將obj的所有屬性克隆到obj2上的所有屬性克隆obj2原型上 對象繼 ...
  • 既然選擇了遠方,便只顧風雨兼程 __ HANS許 系列:零基礎搭建前後端分離項目 系列:零基礎搭建前後端分離項目 創建空項目 使用Less 使用TypeScript 使用WebPack 開始寫項目 總結一下 上篇文章我們講了VsCode的使用以及Node與Npm的使用,並簡單的創建了一個Expres ...
  • js對標簽的操作 創建標簽:document.createElement("tag"); 便簽添加內容 : document.createElement("tag").innerHTML=""; 刪除標簽:找到父標簽再刪除,this.parentNode.removeChild(this)。 js定 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...