動態

詳情 返回 返回

受夠了團隊代碼風格不統一?7千字教你從零搭建代碼規範體系 - 動態 詳情

前言

此篇文章主要講解如何來搭建一套代碼規範體系,主要內容為:通過 ESLint + Prettier + Stylelint 實現代碼風格規範、格式化,通過 EditorConfig 實現 IDE 編碼風格規範化

本文約 7k 字,主要內容分為 7 個大章節,內分多個小章節。請耐心讀完,相信你應該有所收穫

本文也是《通俗易懂的中後台系統建設指南》系列的第四篇文章,該系列旨在告訴你如何來構建一個優秀的中後台管理系統

寫在前面

注意,在文章開始之前,你應該拉起一個 Vue 或者 React 項目,如果沒有,你可以參考收下這份 Vue + TS + Vite 中後台系統搭建指南,從此不再害怕建項目

本文環境中默認你已拉起 Vue3 + TS + Vite 項目,如果你是 React 項目,在不涉及框架方面的內容,你可以適當參考

在下面的篇章中,我們分為兩個層面來構建規範體系:

  • 代碼層面(ESLint + Prettier + Stylelint)
  • IDE 層面(EditorConfig)

下面我們先來介紹一下 ESLint

什麼是 ESLint?

應用官網的話來説:

ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs.

ESLint 是一個用於識別和報告在 ECMAScript/JavaScript 代碼中發現的模式的工具,其目標是使代碼更加一致並避免錯誤。

大白話來説,ESLint 是一個 JavaScript 代碼檢查工具,幫助我們來確保代碼風格一致,這對於團隊協作來説是大有益處,也用來發現一些潛在錯誤或不規範的代碼。ESLint 的規則是可配置的,因此可以根據團隊偏好、項目需求來定義自己的 ESLint 規則

在下面的內容中,我們一致使用最新的大版本 ESLint v9

在 ESLint v9 中,一些比較大的變化是:

  • 對 NodeJS 版本的要求,不再支持 v18.18.0 和 v19 版本
  • 新的默認配置格式:eslint.config.js 和扁平化配置
  • 刪除了大部分的格式化程序,更專注於代碼質量
  • ...

新版本的 ESLint 變化較大,你應該先看看這份遷移指南

截止本文發佈日,ESLint 的最新版本是 v9.16.0

安裝 ESLint

注意,因為我們使用的是 ESLint v9 版本,請確保你的 NodeJS 版本至少大於 18.18.0
通過 node -v 來查看你的 node 版本,且推薦使用 nvm 來管理你的 node 版本

運行命令:

pnpm create @eslint/config@latest

運行後,eslint 會向你詢問一些配置項:

以下打勾的選項表示本文選擇的配置項(本文項目環境默認為 Vue3 + TS)
如果你的項目環境有差異,可自行選擇配置項

How would you like to use ESLint?(您希望如何使用 ESLint)

  1. To check syntax only(只檢查語法)
  2. To check syntax and find problems(檢查語法並發現問題)√

What type of modules does your project use?(你的項目使用什麼類型的模塊?)

  1. JavaScript modules (import/export) (JavaScript模塊(導入/導出)√
  2. CommonJS (require/exports) (CommonJS(需要/出口) )
  3. None of these (這些都不是)

Which framework does your project use?(您的項目使用哪個框架?)

  1. React
  2. Vue.js √
  3. None of these (這些都不是)

Does your project use TypeScript?(你的項目使用TypeScript嗎?)

  1. No
  2. Yes √

Where does your code run?(你的代碼在哪裏運行?)

  1. Browser (瀏覽器) √
  2. Node

Would you like to install them now?(您現在要安裝它們嗎?)

  1. No
  2. Yes √

Which package manager do you want to use?(您想使用哪個包管理器)

  1. npm
  2. yarn
  3. pnpm √
  4. bun

整體的配置如下:
Pasted image 20241125175227

如你所見,命令行配置選擇完成後,會安裝一些依賴到 devDependencies,打開 package.json 文件,找到它們:

{
  "devDependencies": {
    "@eslint/js": "^9.15.0",
    "@vitejs/plugin-vue": "^5.1.4",
    "eslint": "^9.15.0",
    "eslint-plugin-vue": "^9.31.0",
    "globals": "^15.12.0",
    "typescript-eslint": "^8.15.0",
  }
}

下面簡單介紹一下這幾個包:

  • @eslint/js:ESLint 的核心包,用於支持 JavaScript 的代碼分析功能,適用於基於 JavaScript 的代碼檢查
  • @vitejs/plugin-vue:Vite 的官方 Vue 插件,專為 Vue 3 項目設計
  • eslint:ESLint 包
  • eslint-plugin-vue:專為 Vue 項目設計的 ESLint 插件,提供了對 Vue 特有語法(如模板、指令等)的代碼檢查和規則支持
  • globals:JavaScript 全局變量的庫,提供常見的全局變量,通常用於 ESLint 配置中定義哪些全局變量是允許的
  • typescript-eslint:TypeScript 的 ESLint 插件,允許 ESLint 對 TypeScript 代碼進行靜態分析和代碼檢查

然後,在項目根目錄下,你會發現生成了一個 eslint.config.js 文件,它是新的默認配置格式,參閲 新的默認配置格式 (eslint.config.js)

打開這個文件,你的 ESLint 默認配置內容應該是這樣的,它默認導出一個數組:

import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";


/** @type {import('eslint').Linter.Config[]} */
export default [
  {files: ["**/*.{js,mjs,cjs,ts,vue}"]},
  {languageOptions: { globals: globals.browser }},
  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  ...pluginVue.configs["flat/essential"],
  {files: ["**/*.vue"], languageOptions: {parserOptions: {parser: tseslint.parser}}},
];

你可以在這裏獲取配置文件的詳細信息:Configuration Objects 配置對象

注意,請確保在 package.json 中配置了type,指定 ES Module 方式導出

//package.json
{
  "type": "module"
}

VS Code 中集成 ESLint

VS Code 中集成 ESLint 插件,可以幫助你找出代碼中不符合 ESLint 規則的地方,通過不同顏色下劃線該告訴你錯誤信息、警告信息等,這很有用

注意,ESLint 擴展會自動查找 ESLint 全局安裝版本,在項目根目錄下找到你的配置文件(eslint.config.js)

在 VS Code 擴展中搜索 ESLint 插件並安裝:
Pasted image 20241204085545

ESLint 配置

在配置之前,最好先了解一下 ESLint v9 中很重要的變化,Flat Config 即扁平化配置,強烈建議閲讀由 ESLint 創始人Nicholas C. Zakas發佈的此篇文章:扁平化配置簡介

然後,這裏推薦三種配置 ESLint 的方案

  • 快速使用:如果你不想太過折騰配置 ESLint,那麼我會推薦直接使用 antfu 的 eslint-config ,它提供開箱即用的功能,並且支持自定義覆蓋,是一個快速可靠的選擇
  • 動手學習:如果你有很強的好奇心或者動手能力,想一探究竟,那麼我推薦你可以參考 eslint-config 的源碼來配置自己的 ESLint 文件,這能讓你學到更多
  • 進階方式:最後一種進階的方式,即創建修改併發布自己的 eslint-config,這種做法是強大又快捷,並且即插即用,事實上, 一些優秀的開源 Admin 也是如此做的

下面我們會介紹一些配置項屬性的基本使用:

使用  ignores  全局忽略文件

在 ESLint v9 之前,我們通過創建 .eslintignore 來忽略文件,在扁平化配置下,我們需要在 eslint.config.js 中配置 ignores 字段,它是一個字符串數組。可以實現局部忽略,也可以是全局,這取決於是否有 files 字段,參閲 Ignoring Directories 

例如:

//eslint.config.js
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";

/** @type {import('eslint').Linter.Config[]} */
export default [
  //...
  {
    ignores: [
      "**/node_modules",
      "**/public",
      "**/assets",
      "**/dist",
      "**/package-lock.json",
      "**/yarn.lock",
      "**/pnpm-lock.yaml",
      "**/.history",
      "**/CHANGELOG*.md",
      "**/*.min.*",
      "**/LICENSE*",
      "**/__snapshots__",
      "**/auto-import?(s).d.ts",
      "**/components.d.ts",
    ],
  },
];

使用 rules 配置規則

規則是 ESLint 的核心構建塊。@eslint/js 包已經配置了大量規則pluginJs.configs.recommended,當然,你也可以在 rules 中覆蓋這些規則來完成你的需要

以下是一個示例,我們配置一些規則,到 main.ts 中來實驗是否生效


export default [
  //...其他配置
  {
    files: ["src/main.ts"], //確定配置對象應用於哪些文件
    ignores: ["node_modules"], //確定應該忽略哪些文件
    rules: {
      "no-alert": "error", //禁止使用 alert、confirm 和 prompt
      "no-empty-function": "error", //禁止空函數
      "no-var": "error", //禁止使用var
    },
  },
];

查看文件 main.ts
Pasted image 20241126231034

請確保你已經安裝了 ESLint 擴展,否則代碼將不會出現紅色下劃線和報錯信息

另外,我們可以使用命令來在終端輸出全部錯誤:

npx eslint src/main.ts

Pasted image 20241126231119

在命令後面加 --fix 將自動修復可以修復的錯誤

npx eslint src/main.ts  --fix

Pasted image 20241126231144

在上述截圖中,修復操作把 var 轉化為了 let,但下面的 alert 仍然報錯,並非所有問題都能通過修復解決,比如第十二行的 alert 需要手動刪除

這裏有一些 ESLint 規則,你應該要知道:ESLint 規則

使用 plugins 添加插件

ESLint 插件是一個 npm 模塊,可以包含一組 ESLint 規則、配置、處理器和環境,

要在配置文件中配置插件,請使用  plugins

比如,Vue.js 的官方 ESLint 插件 eslint-plugin-vue

import pluginVue from 'eslint-plugin-vue';

export default [
  {
    files: ['**/*.vue'],
    plugins: {
      vue: pluginVue,
    },
  },
];

languageOptions 配置語言選項

ESLint 允許配置特定於項目中使用的 JavaScript 的語言選項,例如自定義全局變量
還可以使用插件來擴展 ESLint 以支持項目的語言選項

languageOptions 是一個對象,它擁有一些配置屬性:

  • ecmaVersion:默認值為 latest,指示正在檢查的代碼的 ECMAScript 版本,確定語法和可用的全局變量
  • sourceType:默認值為 module,指示正在使用的 JavaScript 文件的模式。可能的值為 modulecommonjsscript
  • parserOptions:解析器選項
  • Globals:指定全局變量

詳細瞭解它們,請參閲 Configure Language Options

老實説,這裏列舉太多的配置項意義不大,像是流水線一樣。你可以在 ESLInt 的官網文檔中找到更詳細且全面的介紹,參閲 配置 ESLInt

示例

這裏,我們會實現一個針對 Vue 文件的 ESLInt 配置示例

此配置參考於 antfu 的 eslint-config

首先,需要安裝兩個依賴:

eslint-plugin-vue 插件

Vue.js 的官方 ESLint 插件 - GitHub。如果你是使用上述的命令腳本 @eslint/config 安裝,並且在引導程序選擇框架(Which framework does your project use)時選擇了Vue,那麼這個插件應該是默認已安裝在你的項目中,如果沒有,請使用命令:

pnpm add eslint-plugin-vue --save-dev

vue-eslint-parser 插件
用於 .vue 文件的 ESLint 自定義解析器 - GitHub,請使用命令:

pnpm add vue-eslint-parser --save-dev

然後,在 eslint.config.js 中配置(默認你使用了 TypeScript)

import globals from "globals";
import pluginJs from "@eslint/js";
import tsEslint from 'typescript-eslint';
import pluginVue from "eslint-plugin-vue";
import parserVue from 'vue-eslint-parser';

/** @type {import('eslint').Linter.Config[]} */
export default [
  //...
    {
    files: ['**/*.vue'],
    languageOptions: {
      parser: parserVue,
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
        extraFileExtensions: ['.vue'],
        parser: tsEslint.parser,
        sourceType: 'module',
      },
    },
    plugins: {
      vue: pluginVue,
    },
    processor: pluginVue.processors['.vue'],
    rules: {
      ...pluginVue.configs.base.rules,
      ...pluginVue.configs['vue3-essential'].rules,
      ...pluginVue.configs['vue3-strongly-recommended'].rules,
      ...pluginVue.configs['vue3-recommended'].rules,
      //...更多配置規則
    },
  },
]

VS Code 中配置 ESLint 插件

還記得上述篇章中,我們在 VS Code 中集成了 ESLint 擴展嗎,我們可以在 setting.json 中定義它的配置

.vscode/settings.json (沒有此文件就創建)文件寫入以下配置:

{
    "eslint.useFlatConfig": true, //vscode-eslint >= v8.57.0,確保扁平化配置開啓
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": "explicit" // eslint自動修復
    },
    // 為列表中指定的文件類型啓用 ESLint 驗證
    "eslint.validate": [
      "javascript",
      "javascriptreact",
      "typescript",
      "typescriptreact",
      "vue",
      "html",
      "markdown",
      "json",
      "json5",
      "jsonc",
      "yaml",
      "toml",
      "xml"
    ],
  }
  • eslint.useFlatConfig:ESLInt擴展 8.57.0 及更高版本支持的設置
  • eslint.validate:強制執行驗證設置,僅驗證該列表中的文件
  • "source.fixAll.eslint": "explicit":保存自動修復錯誤

ESLint 腳本命令配置

ESLint CLI 允許從終端來執行 linting,且提供了多個選項來配置 ESLint
比如上面提到的 `npx eslint src/main.ts --fix

在實際項目中,我們會將命令寫在 package.json 的 scripts 裏
比如這樣:

{
  "scripts": {
    "lint:eslint": "eslint --fix  --cache --max-warnings 0  \"src/**/*.{vue,ts,tsx}\"  --cache-location 'node_modules/.cache/eslint/'",
}

解釋一下其中的配置:

  • --max-warnings: 此選項允許您指定警告閾值,如果項目中存在過多的警告級別規則衝突,則該閾值可用於強制 ESLint 退出並顯示錯誤狀態
  • --fix: 指示 ESLint 嘗試修復儘可能多的問題
  • --cache: 存儲有關已處理文件的信息,以便僅對更改的文件進行操作。確保僅對更改的文件進行 linted 處理,從而顯著提高 ESLint 的運行時性能
  • --cache-location: 緩存位置的文件或目錄的路徑,因為緩存會生成一個 .eslintcache 文件,不配置將在根目錄下生成,我們這裏統一處理放在 node_modules/.cache

然後,我們就可以在終端來檢查你的代碼:

pnpm lint:eslint

Pasted image 20241127143018

實戰案例

本系列專欄也提供了一個實戰項目 vue-clean-admin ,上述的 ESLint 配置都能在 eslint.config.js 中找到

在 Vite 中集成 ESLint 插件

這裏推薦一個 Vite 中關於 ESLint 的插件:vite-plugin-eslint
它可以在 Vite 程序中檢查 ESLint 的錯誤,並將其錯誤或警告輸出在終端和頁面上

使用命令

pnpm add vite-plugin-eslint --save-dev

vite.config.ts 中配置:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import eslint from "vite-plugin-eslint";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), eslint()],
});

比如在應用程序頁面中:

Pasted image 20240713214221

終端輸出:
Pasted image 20240713214333

FAQ

如果你的 VS Code 已集成 ESLint 插件,但代碼未有錯誤提示,請在 VS Code 終端的輸出頁查看插件信息及是否報錯,右側下拉框記得選擇 ESLint

Pasted image 20240825222553

關於 ESLInt 更多信息

你可以在 awesome-eslint存儲庫中找到 ESLint 的其他流行集成的精選列表。

什麼是 Prettier?

Prettier 是一個代碼格式化工具,主要用於自動化代碼的風格統一和格式化,專注於確保代碼的可讀性和一致性

在官網的介紹是:一個固執己見的代碼格式化程序

安裝 Prettier

pnpm add --save-dev --save-exact prettier

配置 Prettier

在根目錄下新增兩個文件:

  • .prettierignore 忽略文件,表示哪些文件忽略格式化,官網説明
  • .prettierrc.js Prettier 配置文件(ES Modules)

.prettierignore 忽略文件:

要忽略什麼文件,這取決於你的項目,比如:

dist
public/*
src/assets/*

.prettierrc.js 配置文件:

配置文件寫入你的格式化配置,在這裏查看 Prettier 可配置項

比如:

/** @type {import('prettier').Config} */
const config = {
  printWidth: 100, // 每行最大字符數
  tabWidth: 2, // 縮進空格數
  semi: true, // 尾部添加分號
  singleQuote: true, // 是否使用單引號而不是雙引號
  bracketSpacing: true, // 在對象字面量的括號內添加空格
  arrowParens: 'always', // 總是為箭頭函數的參數添加圓括號
  proseWrap: 'preserve', // 不改變 Markdown 文本的換行
  bracketSameLine: false,
};

export default config;

VS Code 中集成 Prettier

在 VS Code 擴展中搜索 Prettier 並進行安裝
Pasted image 20241204085658

Prettier 擴展會自動查找項目根目錄下的配置文件、忽略文件,下面我們針對擴展進一步配置,

保存時格式化代碼、且指定 Prettier 插件來格式化代碼寫進 settings.json

{
  "editor.formatOnSave": true, //保存時自動格式化
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}
文本 esbenp.prettier-vscode 是 VS Code 中 Prettier 插件的標識符

Prettier 腳本命令配置

在你的 package.json 的 scripts 下新增腳本

{
  "scripts": {
    "lint:format": "prettier  --write --cache \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
}
  • --write:這將就地重寫所有已處理的文件。這與  eslint --fix  工作流程相當。您也可以使用  -w  別名。
  • --cache: 存儲有關已處理文件的信息,以便僅對更改的文件進行操作

然後就可以在終端來格式化你的代碼:

pnpm lint:format

ESLint 和 Prettier 配合使用

在 ESLint v9.0.0 前的格式化程序和 Prettier 起衝突,這是一個常常發生的事情

這裏介紹兩個依賴:

  • eslint-config-prettier:關閉所有不必要或可能與 Prettier 衝突的規則 - GitHub
  • eslint-plugin-prettier:將 Prettier 作為規則插入到 ESLint 裏 - GitHub

    eslint-config-prettier 依賴

eslint-config-prettier 用於關閉所有不必要或可能與 Prettier 衝突的規則

在 ESLint v9 已經移除了多個內置的格式化規則,使其更專注於代碼質量檢查而非格式,參閲 ESLint v9 遷移指南,這意味着 eslint-config-prettier 的用武之地有所減少

不過,一些廣泛使用的 ESLint 插件可能仍然包含格式化相關的規則,比如 eslint-plugin-vue 的規則 :

    rules: {
      "vue/max-attributes-per-line": "off",
      "vue/singleline-html-element-content-newline": "off", 
      "vue/multiline-html-element-content-newline": "off",
    },

對於這種情況,有兩種方案:

  1. 手動關閉衝突的規則
  2. 使用插件 eslint-config-prettier

手動關閉具有精準性,為未來調整保留了靈活性,而 eslint-config-prettier 則是具有便捷性

選擇哪種方式取決於你的項目需求和個人偏好。這裏選擇手動關閉規則,保持精準控制和靈活性。如果你需要使用 eslint-config-prettier ,請看相關 README

eslint-plugin-prettier 依賴

將 Prettier 作為規則插入到 ESLint 裏,安裝 eslint-plugin-prettier

pnpm add --save-dev eslint-plugin-prettier

eslint.config.js 中引入

//...其他依賴
import pluginPrettier from "eslint-plugin-prettier";

/** @type {import('eslint').Linter.Config[]} */
export default [
  //...
  {
    plugins: {
      prettier: pluginPrettier,
    },
    rules: {
      "prettier/prettier": "error",
    },
  },
];

爭議的 Prettier

Prettier is an opinionated code formatter
Prettier 是一個固執己見的代碼格式化程序

推薦閲讀 antfu 的 Why I don't use Prettier

討論:https://github.com/eslint/eslint.org/issues/435

其他:ESLint Stylistic、ESLint團隊終於妥協了

什麼是 Stylelint?

一個強大的 CSS 檢測工具,可幫助您避免錯誤並執行約定,官網

安裝 Stylelint

pnpm add stylelint --save-dev

VS Code 中集成 Stylelint

在 VS Code 擴展模塊搜索 Stylelint 進行安裝,或者點擊此鏈接:stylelint 插件

Pasted image 20241204093912

VS Code 中配置 Stylelint 插件

settings.json 文件中寫入以下配置:

之前我們已經配置過了 ESLint,這裏的 Stylelint 類似
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": "explicit",
      "source.fixAll.stylelint": "explicit",//配置 stylelint 保存自動修復
    },
    "stylelint.validate": ["css", "less", "scss", "sass", "postcss", "vue"]//插件檢查範圍

Stylelint 配置文件

在根目錄下新建一個 stylelint.config.js 文件,同時確保你的 package.json 配置了 "type": "module",表示使用 ESM 模塊導出

然後,就像官網的示例一樣,在 stylelint.config.js 文件寫入:

/** @type {import('stylelint').Config} */
export default {
    rules: {
      "block-no-empty": true, //禁止空塊,比如 a{ }
    },
};

.stylelintignore 忽略文件

同樣的,在根目錄下新建一個 .stylelintignore 文件,表示忽略特定文件

node_modules
dist
public
src/assets/*

注意,在 stylelint.config.js 文件也有一個 ignoreFiles 屬性,表示忽略特定文件

/** @type {import('stylelint').Config} */
export default {
  ignoreFiles: ["**/*.json", "**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx"],
};

但這不是忽略大量文件的有效方法。如果想有效地忽略大量文件,請在單獨的  .stylelintignore 文件內寫入

Stylelint 依賴安裝

簡單來説,Stylelint 和 ESLint 很類似,都是定義規則、風格來進行代碼檢查,保證代碼風格一致性,並發現一些潛在錯誤或不規範的代碼。不同在於 Stylelint 針對的是 CSS 樣式的代碼檢查

下面介紹一些 Stylelint 相關的依賴:

pnpm add stylelint-config-standard stylelint-config-standard-scss --save-dev
  • stylelint-config-standard:Stylelint 的 CSS 標準配置 - GitHub
  • stylelint-config-standard-scss:Stylelint 的標準可共享 SCSS 配置。
  • Scss:stylelint-config-recommended-scss:Stylelint 推薦的可共享 SCSS 配置
pnpm add stylelint-config-recommended-vue stylelint-config-recess-order stylelint-config-html --save-dev
  • stylelint-config-recommended-vue:擴展 stylelint-config-recommended 配置,並提供推薦的 Vue 相關規則,GitHub
  • stylelint-config-recess-order:對 CSS 屬性進行排序 - GitHub
  • stylelint-config-html:此配置捆綁  postcss-html  自定義語法並對其進行配置 - GitHub
pnpm add postcss postcss-html postcss-scss --save-dev
# 如果你使用的是Less,把 postcss-scss 替換成 postcss-less
  • postcss:使用 JavaScript 轉換 CSS 的工具,官網
  • postcss-html: 用於解析 HTML(和類 HTML)的 PostCSS 語法,比如 Vue SFC 文件 - GitHub
  • Less:postcss-less:用於解析 Less 的 PostCSS 語法 - GitHub
  • Scss:postcss-scss: 用於解析 Scss 的 PostCSS 語法 - GitHub

上面的依賴中,除了可選的 Less 和 Scss 外,其餘依賴建議全部安裝(默認你使用 Vue 框架),具體使用方法先看簡介後面給出的 GitHub 鏈接

由於此專欄也提供了一個實戰項目,你也可以看這裏,上述中的所有配置都寫入在內

與 Prettier 配合

在 ESLint 部分,我們為配合 Prettier 時介紹了兩個包, eslint-config-prettiereslint-plugin-prettier

而在 Stylelint 中,也有類似的包,分別是

  • stylelint-config-prettier,用於解決 Stylelint 和 Prettier 之間的規則衝突問題
  • stylelint-prettier,作為 Stylelint 規則運行 Prettier,並將差異報告為單獨的 Stylelint 問題

但是,stylelint-config-prettier 包現在已經不維護了,因為從 Stylelint v15 開始,所有與樣式相關的格式規則都已被棄用,比如那些強制執行特定代碼風格或格式的規則,參閲 Stylelint 15.0.0 版本
如果您使用的是 v15 或更高版本,並且沒有使用這些已棄用的規則,則不再需要此插件

Stylelint 跟隨着 ESLint 的腳步,更專注於代碼質量而非格式

所以我們這裏只安裝 stylelint-prettier - GitHub

注意,請確保你已經安裝了 Stylelint 和 Prettier
pnpm add stylelint-prettier --save-dev

然後在 stylelint.config.js 中配置

/** @type {import('stylelint').Config} */

export default {
  plugins: ["stylelint-prettier"],
  rules: {
    "prettier/prettier": true,
  },
};

stylelint.config.js 配置

在上述篇章中,我們安裝了很多的依賴,現在我們來配置他們,在這之前先來了解一下 stylelint 文件的 Config,如果你對 ESLint 很熟悉,那麼對 Stylelint 配置項也不會陌生

extends 擴展現有配置

擴展現有配置(無論是你自己的還是第三方的)。配置可以捆綁插件、自定義語法、選項和配置規則

比如,引入我們之前安裝的依賴包:

/**@type {import('stylelint').Config} */
export default {
  extends: [
    "stylelint-config-standard",
    "stylelint-config-recess-order",
    "stylelint-config-html",
  ]
}

rules 規則

同 ESLint 一樣,rules 屬性用來自定義規則,Stylelint 已經內置了一些規則,在這裏找到它們,比如:

/**@type {import('stylelint').Config} */
export default {
  //...
  rules: {
    "block-no-empty": true,// 禁止空塊
    'max-nesting-depth': 3,// 限制嵌套層數
  }
};

overrides 指定應用的文件

使用該  overrides  屬性,可以指定要應用配置的文件子集,參閲 overrides,比如可以針對類型文件進行配置:

{
  overrides: [
    {
      files: ["*.less", "**/*.less"],
      customSyntax: "postcss-less",
      extends: ['stylelint-config-standard', 'stylelint-config-recommended-vue']
    },
    {
      files: ["*.scss", "**/*.scss"],
      customSyntax: "postcss-scss",
      extends: ["stylelint-config-standard-scss", "stylelint-config-recommended-vue/scss"],
    },
}

示例

結合上面的基本配置,stylelint.config.js 配置可以是這樣的:

假設你使用 Vue 框架,並且安裝了 Tailwind Css 和 Scss
/** @type {import('stylelint').Config} */
export default {
  extends: ["stylelint-config-standard", "stylelint-config-recess-order", "stylelint-config-html"],
  plugins: ["stylelint-prettier"],
  rules: {
    "prettier/prettier": true,
    "no-empty-source": null,
    "import-notation": null,
    "at-rule-no-unknown": [
      true,
      {
        ignoreAtRules: [
          "tailwind",
          "apply",
          "variants",
          "responsive",
          "screen",
          "use",
          "mixin",
          "include",
          "extend",
        ],
      },
    ],
    "selector-pseudo-class-no-unknown": [
      true,
      {
        ignorePseudoClasses: ["global", "deep"],
      },
    ],
  },
  overrides: [
    {
      files: ["*.scss", "**/*.scss"],
      customSyntax: "postcss-scss",
      extends: ["stylelint-config-standard-scss", "stylelint-config-recommended-vue/scss"],
    },
    {
      files: ["*.vue", "**/*.vue", "*.html", "**/*.html"],
      customSyntax: "postcss-html",
      extends: ["stylelint-config-standard", "stylelint-config-recommended-vue"],
    },
  ],
  ignoreFiles: [
    "**/*.js",
    "**/*.jsx",
    "**/*.ts",
    "**/*.tsx",
    "**/*.json",
    "**/*.md",
    "**/*.yaml",
    "**/*.yml",
    "**/*.d.ts",
  ],
};

我們來測試一下是否生效,比如一個 css 文件有這麼一段代碼:

.box {
  background-color: red;
  border: none;

  width: 100%;
  height: 100%;
}

.title {
}

在 VS Code 中安裝了 Stylelint 插件後 ,你可以看到如下報錯:

Pasted image 20240826170722

這段css代碼中會標記三個問題:

  • 排序問題,來自於 stylelint-config-recess-order
  • 意外的空行問題,來自於stylelint-config-standard
  • 空代碼塊問題,來自於stylelint-config-standard

其中,前兩個問題可以通過保存使其自動修復

空代碼塊問題則需要配置規則

/**@type {import('stylelint').Config} */
export default {
  rules: {
    "block-no-empty": null,//關閉空代碼塊規則
  },
}

如果沒有消除報錯,在 VS Code 中,打開命令面板,搜索 Reload ,回車選中來重新加載窗口

Win 使用 Ctrl + Shift + P 打開命令面板,Mac 使用 Command + Shift + P

FAQ

tailwind css 文件報錯 Unexpected unknown at-rule "@tailwind"

答:在文件 stylelint.config.js 中配置規則:

/**@type {import('stylelint').Config} */

export default {
  rules: {
    "at-rule-no-unknown": [
      true,
      {
        ignoreAtRules: ["tailwind", "apply"],
      },
    ],
  },
}
無效果請先重新加載 VS Code 窗口

stylelint 腳本命令配置

{
  "scripts": {
    "lint:style": "stylelint --fix --max-warnings 0 --cache \"**/*.{css,scss,sass,vue}\" --cache-location 'node_modules/.cache/stylelint/'"
}
  • --fix:自動修復規則報告的問題
  • --max-warnings:設置接受的警告數量限制
  • --cache:存儲已處理文件的結果,以便 Stylelint 僅對更改的文件進行操作
  • --cache-location:作用同 ESLint,將緩存文件放在 node_modules/.cache

然後就可以在終端執行命令來調用腳本:

pnpm lint:style

什麼是 EditorConfig?

EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs
EditorConfig 有助於為跨各種編輯器和 IDE 處理同一項目的多個開發人員保持一致的編碼風格

簡單來説,EditorConfig 幫助我們在不同 IDE 編輯器中維持一致的編碼風格和格式化規範,比如縮進,字符編碼等,官網

.editorconfig 配置

我們在根目錄下新建一個 .editorconfig 文件,並寫入以下配置
下列配置項給出了其配置解釋,當然,配置不止這些,你可以在這裏找到更多

# 官網:https://editorconfig.org/
root = true # 表示最頂層的 EditorConfig 文件,即停止向上找,直接使用該配置文件

[*] # 匹配所有文件
charset = utf-8 # 控制字符集
indent_style = space # 縮進方式 (tabl | space)
indent_size = 2 # 縮進大小

end_of_line = lf # 設置換行符的類型。可選值為 lf(Unix 風格)、cr(Mac 風格)或 crlf(Windows 風格)。
insert_final_newline = true # 是否在文件末尾插入一個空行,以確保文件總是以換行符結尾
trim_trailing_whitespace = true # 是否保存文件時刪除行尾的空白字符

VS Code 集成 EditorConfig

VS Code 本身不支持 EditorConfig,我們通過插件來使用

WebStorm 原生支持,無須安裝插件

在 VS Code 擴展模塊搜索 EditorConfig 進行安裝,或者點擊此鏈接:EditorConfig for VS Code
Pasted image 20241204094520

插件會在根目錄下找到配置文件,讀取 .editorconfig 文件中定義的規則,並覆蓋工作區的對應配置

聚合豐富配置

以下配置是可選的,請根據自己的需求選擇

腳本命令

上面我們配置了 ESLint、Prettier、Stylelint的腳本命令,我們可以寫一個聚合的命令,統一執行我們的三條腳本

確保你已經定義過 lint:eslintlint:formatlint:style 這三個腳本命令,如果沒有,請看上文
{
  "scripts": {
    "lint": "pnpm lint:format && pnpm lint:eslint && pnpm lint:style",
  }
}

注意這裏的順序,我們應該先格式化代碼後再調用 ESLint,Stylelint 進行代碼檢查

緩存文件刪除

在上面的 Eslint 和 Stylelint 命令中,會生成緩存文件,這些文件存在 node_modules/.cache 目錄中,有些時候我們可以刪除這些緩存,它的作用在於刪除緩存會強制重新檢查所有文件,而不是依賴可能過時的緩存結果
Pasted image 20241203222723

rimraf 是一個跨平台的刪除工具,我們藉助它來刪除緩存文件

安裝 rimraf

pnpm add -D rimraf

package.jsonscripts 中寫入刪除緩存文件腳本:

  "scripts": {
    "clear:cache": "rimraf node_modules/.cache",
  }

然後就可以在終端執行命令來刪除 node_modules/.cache 文件:

pnpm clear:cache

文件摺疊

上文配置中,ESLint、Stylelint、Prettier都有其配置文件及忽略文件等,可以在 VS Code 中寫入配置來摺疊它們,顯得整潔

.vscode/settings.json 中寫入以下配置:

  "explorer.fileNesting.enabled": true, //是否啓用文件摺疊
  "explorer.fileNesting.expand": false, //控制是否自動擴展文件嵌套
  "explorer.fileNesting.patterns": {
    "eslint.config.js": ".prettierrc.*, stylelint.*, .editorconfig, .prettierignore, .stylelintignore",
  },
假設你的配置文件與本文一致,此配置應該是這樣的。你也可以自行配置摺疊規則

Pasted image 20240731142852

參考資料

  • ESLint+Prettier+Stylelint+EditorConfig 約束和統一前端代碼規範
  • 嚐鮮 ESLint v9 版本 扁平模式(Flat Config)如何配置
  • 不以規矩,不能成方圓-徹底搞懂 ESLint 和 Prettier

瞭解更多

系列專欄地址:GitHub(推薦) | 掘金專欄 | 思否專欄
實戰項目:vue-clean-admin

專欄往期回顧:

  1. 收下這份 Vue + TS + Vite 中後台系統搭建指南,從此不再害怕建項目
  2. 中後台開發必修課:Vue 項目中 Pinia 與 Router 完全攻略
  3. 用了這些 Vite 配置技巧,同事都以為我開掛了

    交流討論

文章如有錯誤或需要改進之處,歡迎指正

user avatar alibabawenyujishu 頭像 haoqidewukong 頭像 smalike 頭像 kobe_fans_zxc 頭像 yelloxing 頭像 chongdianqishi 頭像 banana_god 頭像 xiaoxxuejishu 頭像 zero_dev 頭像 woniuseo 頭像 guixiangyyds 頭像 yuzhihui 頭像
點贊 105 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.