轩辕李的博客 轩辕李的博客
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

轩辕李

勇猛精进,星辰大海
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Node.js

  • Vue.js

  • 工程化

    • Vite极简入门
    • 前端代码质量工具链详解
      • 一、代码质量概述
        • 为什么需要代码质量工具
        • 工具链全景图
        • 工具分类
      • 二、ESLint - 代码规范
        • ESLint 简介
        • 安装和初始化
        • 配置文件
        • 常用规则配置
        • TypeScript 项目配置
        • Vue 项目配置
        • React 项目配置
        • 使用 ESLint
        • package.json 脚本
        • 忽略文件
      • 三、Prettier - 代码格式化
        • Prettier 简介
        • 安装
        • 配置文件
        • 忽略文件
        • 与 ESLint 集成
        • 使用 Prettier
        • package.json 脚本
        • 编辑器集成
        • VS Code
      • 四、TypeScript - 类型检查
        • TypeScript 配置详解
        • tsconfig.json 严格模式
        • 类型检查最佳实践
        • 在构建时进行类型检查
        • Vue 项目类型检查
        • 类型声明文件
      • 五、Stylelint - 样式规范
        • Stylelint 简介
        • 安装
        • 配置文件
        • 使用 Stylelint
      • 六、Git Hooks - 提交前检查
        • Husky - Git Hooks 管理
        • 配置 pre-commit 钩子
        • lint-staged - 暂存文件检查
        • Commitlint - 提交信息规范
        • 完整的 Git Hooks 配置
      • 七、EditorConfig - 编辑器配置
        • 什么是 EditorConfig
        • 安装
        • 配置文件详解
        • 支持的配置选项
        • 最佳实践
      • 八、编辑器集成
        • VS Code 配置
        • 推荐插件
        • 工作区配置
        • WebStorm / IntelliJ IDEA 配置
      • 九、CI/CD 集成
        • GitHub Actions
        • GitLab CI
      • 十、最佳实践总结
        • 1. 渐进式采用
        • 2. 团队规范
        • 3. 性能优化
        • 4. 规则制定
        • 5. 工具选择
      • 十一、学习资源
        • 官方文档
        • 推荐资源
        • 相关文章
  • 浏览器与Web API

  • 前端
  • 工程化
轩辕李
2025-06-10
目录

前端代码质量工具链详解

本文面向前端开发者,系统讲解现代前端项目中代码质量保障工具链的配置和使用。涵盖 ESLint(代码规范)、Prettier(格式化)、TypeScript(类型检查)、Stylelint(样式规范)等工具的最佳实践。

# 一、代码质量概述

# 为什么需要代码质量工具

  1. 统一代码风格:团队协作中保持一致的代码风格
  2. 减少错误:编译时发现潜在问题,避免运行时错误
  3. 提高可维护性:规范的代码更易理解和维护
  4. 提升开发效率:自动化工具减少人工审查工作
  5. 降低技术债务:及早发现和修复代码问题

# 工具链全景图

┌─────────────────────────────────────────────────────────┐
│                     代码质量工具链                        │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │   ESLint     │  │  TypeScript  │  │  Prettier    │  │
│  │  代码规范     │  │   类型检查    │  │  代码格式化   │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │
│  │  Stylelint   │  │  Commitlint  │  │    Husky     │  │
│  │  样式规范     │  │  提交规范     │  │  Git Hooks   │  │
│  └──────────────┘  └──────────────┘  └──────────────┘  │
│                                                          │
│  ┌──────────────┐  ┌──────────────┐                    │
│  │ lint-staged  │  │  EditorConfig│                    │
│  │  暂存区检查   │  │  编辑器配置   │                    │
│  └──────────────┘  └──────────────┘                    │
│                                                          │
└─────────────────────────────────────────────────────────┘

# 工具分类

工具 类型 主要功能 运行时机
ESLint 代码检查 JavaScript/TypeScript 代码规范 编辑器、提交前、CI/CD
TypeScript 类型检查 静态类型检查 编辑器、构建时、CI/CD
Prettier 代码格式化 统一代码格式 编辑器保存、提交前
Stylelint 样式检查 CSS/SCSS/Less 规范 编辑器、提交前
Commitlint 提交检查 Git 提交信息规范 提交时
Husky Git Hooks 执行 Git 钩子 Git 操作时
lint-staged 暂存检查 只检查暂存文件 提交前

# 二、ESLint - 代码规范

# ESLint 简介

ESLint 是一个插件化的 JavaScript 代码检查工具,用于识别和报告代码中的模式,帮助开发者编写一致性和无错误的代码。

# 安装和初始化

# 安装 ESLint
npm install -D eslint

# 初始化配置(交互式)
npx eslint --init

# 或者手动创建配置文件

# 配置文件

ESLint 支持多种配置文件格式:

// .eslintrc.js(推荐)
module.exports = {
  // 运行环境:指定代码运行的环境,决定哪些全局变量可用
  env: {
    browser: true,    // 浏览器全局变量(如 window、document)
    es2021: true,     // ES2021 语法和全局变量(如 Promise、Set)
    node: true        // Node.js 全局变量和作用域(如 global、process)
  },
  
  // 继承的规则集:从预设配置中继承规则,避免从零配置
  extends: [
    'eslint:recommended',                          // ESLint 内置的推荐规则集
    'plugin:@typescript-eslint/recommended',       // TypeScript 推荐规则(需要安装 @typescript-eslint/eslint-plugin)
    'plugin:vue/vue3-recommended',                 // Vue 3 推荐规则(需要安装 eslint-plugin-vue)
    'plugin:prettier/recommended'                  // Prettier 集成,关闭与 Prettier 冲突的 ESLint 规则(需要安装 eslint-plugin-prettier 和 eslint-config-prettier)
  ],
  
  // 解析器:指定 ESLint 使用的解析器来解析代码
  parser: '@typescript-eslint/parser',  // 使用 TypeScript 解析器,支持解析 TypeScript 语法(需要安装 @typescript-eslint/parser)
  
  // 解析器选项:配置解析器的行为
  parserOptions: {
    ecmaVersion: 'latest',    // 支持最新的 ECMAScript 语法
    sourceType: 'module',     // 代码是 ECMAScript 模块(使用 import/export)
    ecmaFeatures: {
      jsx: true               // 启用 JSX 语法支持(用于 React)
    }
  },
  
  // 插件:扩展 ESLint 功能的第三方插件
  plugins: [
    '@typescript-eslint',     // TypeScript 支持(提供 TypeScript 特定的规则)
    'vue'                     // Vue.js 支持(提供 Vue 特定的规则)
  ],
  
  // 自定义规则:覆盖或添加具体的检查规则
  // 规则值:'off' 或 0(关闭)、'warn' 或 1(警告)、'error' 或 2(错误)
  rules: {
    // 关闭规则:允许使用 console(开发时常用)
    'no-console': 'off',
    
    // 警告级别:未使用的变量会触发警告但不阻止提交
    'no-unused-vars': 'warn',
    
    // 错误级别:违反规则会报错
    'semi': ['error', 'never'],      // 禁止使用分号(自动修复)
    'quotes': ['error', 'single'],   // 强制使用单引号(自动修复)
    
    // TypeScript 特定规则
    '@typescript-eslint/no-explicit-any': 'warn',              // 警告使用 any 类型(鼓励使用更具体的类型)
    '@typescript-eslint/explicit-function-return-type': 'off', // 关闭强制函数返回类型注解(TypeScript 可以推断)
    
    // Vue 特定规则
    'vue/multi-word-component-names': 'off',  // 关闭组件名必须多词的要求(Vue 推荐但可能过于严格)
    'vue/max-attributes-per-line': ['error', {
      singleline: 3,   // 单行标签允许最多 3 个属性
      multiline: 1     // 多行标签每行只允许 1 个属性
    }]
  },
  
  // 忽略文件:不对以下文件/目录进行检查
  ignorePatterns: [
    'dist',           // 构建输出目录
    'node_modules',   // 依赖包目录
    '*.config.js'     // 配置文件(通常使用 CommonJS 语法,可能与项目规则冲突)
  ]
}

# 常用规则配置

// .eslintrc.js
module.exports = {
  rules: {
    // ===== 代码质量 =====
    'no-console': 'warn',              // 禁止 console(开发时警告)
    'no-debugger': 'error',            // 禁止 debugger
    'no-unused-vars': 'warn',          // 未使用的变量
    'no-undef': 'error',               // 未定义的变量
    'no-var': 'error',                 // 禁止使用 var
    'prefer-const': 'error',           // 优先使用 const
    'eqeqeq': ['error', 'always'],     // 强制使用 ===
    
    // ===== 代码风格 =====
    'semi': ['error', 'never'],        // 不使用分号
    'quotes': ['error', 'single'],     // 使用单引号
    'indent': ['error', 2],            // 2 空格缩进
    'comma-dangle': ['error', 'never'], // 禁止尾随逗号
    'arrow-parens': ['error', 'always'], // 箭头函数参数括号
    
    // ===== 最佳实践 =====
    'curly': ['error', 'all'],         // 强制使用花括号
    'default-case': 'error',           // switch 需要 default
    'no-else-return': 'error',         // 禁止 if 后不必要的 else
    'no-empty-function': 'warn',       // 禁止空函数
    'no-eval': 'error',                // 禁止 eval
    'no-implied-eval': 'error',        // 禁止隐式 eval
    
    // ===== ES6 =====
    'arrow-spacing': 'error',          // 箭头函数空格
    'no-duplicate-imports': 'error',   // 禁止重复导入
    'prefer-arrow-callback': 'error',  // 优先使用箭头函数
    'prefer-template': 'error'         // 优先使用模板字符串
  }
}

# TypeScript 项目配置

# 安装依赖
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin
// .eslintrc.js
module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: './tsconfig.json',
    tsconfigRootDir: __dirname,
    sourceType: 'module'
  },
  plugins: ['@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking'
  ],
  rules: {
    // TypeScript 特定规则
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-explicit-any': 'warn',
    '@typescript-eslint/no-unused-vars': ['warn', {
      argsIgnorePattern: '^_'
    }],
    '@typescript-eslint/no-non-null-assertion': 'warn',
    
    // 覆盖基础规则
    'no-unused-vars': 'off',
    '@typescript-eslint/no-unused-vars': 'warn'
  }
}

# Vue 项目配置

# 安装依赖
npm install -D eslint-plugin-vue
// .eslintrc.js
module.exports = {
  extends: [
    'plugin:vue/vue3-recommended',
    '@vue/typescript/recommended'
  ],
  rules: {
    // Vue 规则
    'vue/multi-word-component-names': 'off',
    'vue/no-v-html': 'warn',
    'vue/require-default-prop': 'error',
    'vue/require-prop-types': 'error',
    'vue/component-name-in-template-casing': ['error', 'PascalCase'],
    'vue/html-indent': ['error', 2],
    'vue/max-attributes-per-line': ['error', {
      singleline: 3,
      multiline: 1
    }],
    'vue/first-attribute-linebreak': ['error', {
      singleline: 'ignore',
      multiline: 'below'
    }]
  }
}

# React 项目配置

# 安装依赖
npm install -D eslint-plugin-react eslint-plugin-react-hooks
// .eslintrc.js
module.exports = {
  extends: [
    'plugin:react/recommended',
    'plugin:react-hooks/recommended'
  ],
  settings: {
    react: {
      version: 'detect'
    }
  },
  rules: {
    'react/react-in-jsx-scope': 'off',  // React 17+ 不需要
    'react/prop-types': 'off',          // 使用 TypeScript
    'react-hooks/rules-of-hooks': 'error',
    'react-hooks/exhaustive-deps': 'warn'
  }
}

# 使用 ESLint

# 检查所有文件
npx eslint .

# 检查特定文件
npx eslint src/**/*.ts

# 自动修复
npx eslint . --fix

# 指定格式输出
npx eslint . --format stylish

# 忽略警告,只显示错误
npx eslint . --quiet

# package.json 脚本

{
  "scripts": {
    "lint": "eslint . --ext .js,.ts,.vue",
    "lint:fix": "eslint . --ext .js,.ts,.vue --fix"
  }
}

# 忽略文件

# .eslintignore
dist
node_modules
*.config.js
public
.nuxt
.output
coverage

# 三、Prettier - 代码格式化

# Prettier 简介

Prettier 是一个有主见的代码格式化工具,支持多种语言,与 ESLint 配合使用可以实现代码规范和格式化的完美结合。

Prettier vs ESLint:

  • ESLint:关注代码质量(潜在错误、最佳实践)
  • Prettier:关注代码风格(缩进、引号、换行)

# 安装

# 安装 Prettier
npm install -D prettier

# 安装 ESLint 集成插件
npm install -D eslint-config-prettier eslint-plugin-prettier

# 配置文件

// .prettierrc.js
module.exports = {
  // 行宽:一行代码的最大字符数,超过会自动换行
  printWidth: 80,
  
  // 缩进宽度:一个缩进等于多少个空格
  tabWidth: 2,
  // 是否使用制表符(Tab)缩进,false 表示使用空格
  useTabs: false,
  
  // 分号:语句末尾是否添加分号(false = 不添加)
  semi: false,
  
  // 引号:字符串使用单引号还是双引号
  singleQuote: true,  // true = 单引号,false = 双引号
  
  // 对象属性引号:何时给对象属性名加引号
  // 'as-needed' = 仅在需要时加引号(如属性名包含特殊字符)
  // 'consistent' = 同一对象中保持一致
  // 'preserve' = 保留原有引号
  quoteProps: 'as-needed',
  
  // JSX 引号:JSX 属性使用单引号还是双引号
  jsxSingleQuote: false,  // false = 双引号(符合 HTML 习惯)
  
  // 尾随逗号:多行时是否在最后一项后添加逗号
  // 'none' = 不添加
  // 'es5' = 在 ES5 有效的地方添加(对象、数组)
  // 'all' = 尽可能添加(包括函数参数)
  trailingComma: 'none',
  
  // 对象字面量空格:大括号内是否添加空格
  // true = { foo: bar }
  // false = {foo: bar}
  bracketSpacing: true,
  
  // JSX 标签闭合:多行 JSX 元素的 `>` 是否单独一行
  // false = 单独一行
  // true = 放在最后一行末尾
  bracketSameLine: false,
  
  // 箭头函数参数括号:单参数箭头函数是否需要括号
  // 'always' = 总是添加括号 (x) => x
  // 'avoid' = 尽可能省略括号 x => x
  arrowParens: 'always',
  
  // 换行符:使用哪种换行符
  // 'lf' = Linux/macOS 风格 (\n)
  // 'crlf' = Windows 风格 (\r\n)
  // 'cr' = 旧 macOS 风格 (\r)
  // 'auto' = 保持现有换行符
  endOfLine: 'lf',
  
  // Vue 文件中的 script 和 style 标签缩进
  // false = 不缩进(与标签同级)
  // true = 缩进一级
  vueIndentScriptAndStyle: false,
  
  // HTML 空白敏感度:如何处理 HTML 中的空白字符
  // 'css' = 遵循 CSS display 属性(推荐)
  // 'strict' = 所有空白都敏感
  // 'ignore' = 所有空白都不敏感
  htmlWhitespaceSensitivity: 'css'
}
  endOfLine: 'lf',
  
  // Vue 文件中的 script 和 style 标签缩进
  vueIndentScriptAndStyle: false,
  
  // HTML 空白敏感度
  htmlWhitespaceSensitivity: 'css'
}

# 忽略文件

# .prettierignore
dist
node_modules
*.config.js
public
.nuxt
.output
coverage
pnpm-lock.yaml
package-lock.json

# 与 ESLint 集成

// .eslintrc.js
module.exports = {
  extends: [
    // ... 其他配置
    'plugin:prettier/recommended'  // 必须放在最后
  ]
}

这个配置做了三件事:

  1. 启用 eslint-plugin-prettier
  2. 设置 prettier/prettier 规则为 error
  3. 使用 eslint-config-prettier 关闭 ESLint 中与 Prettier 冲突的规则

# 使用 Prettier

# 格式化所有文件
npx prettier --write .

# 检查文件是否已格式化
npx prettier --check .

# 格式化特定文件
npx prettier --write "src/**/*.{js,ts,vue}"

# package.json 脚本

{
  "scripts": {
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}

# 编辑器集成

# VS Code

安装 Prettier 插件,然后配置:

// .vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

# 四、TypeScript - 类型检查

# TypeScript 配置详解

如果你还不熟悉 TypeScript 基础,建议先阅读 TypeScript极简入门。

# tsconfig.json 严格模式

{
  "compilerOptions": {
    // ===== 基础配置 =====
    // 编译目标:将 TypeScript 编译成的 JavaScript 版本
    "target": "ES2020",
    
    // 模块系统:生成的模块代码格式
    // 'ESNext' = 使用最新的 ES 模块语法(import/export)
    "module": "ESNext",
    
    // 类型库:编译时包含的类型声明文件
    "lib": ["ES2020", "DOM", "DOM.Iterable"],  // ES2020 API + 浏览器 DOM API
    
    // 模块解析策略:如何查找导入的模块
    // 'bundler' = 适配 Vite、Webpack 等打包工具(推荐)
    // 'node' = Node.js 风格解析
    "moduleResolution": "bundler",
    
    // 是否允许导入 .json 文件作为模块
    "resolveJsonModule": true,
    
    // ===== 路径配置 =====
    // 基础路径:相对路径的起点(通常是项目根目录)
    "baseUrl": ".",
    
    // 路径别名:简化导入路径
    // 使用 '@/utils/helper' 代替 '../../utils/helper'
    "paths": {
      "@/*": ["./src/*"],                    // @ 指向 src 目录
      "@components/*": ["./src/components/*"],
      "@utils/*": ["./src/utils/*"]
    },
    
    // ===== 输出配置 =====
    // 编译输出目录
    "outDir": "./dist",
    
    // 源代码根目录
    "rootDir": "./src",
    
    // 是否生成 .d.ts 类型声明文件(供其他项目使用)
    "declaration": true,
    
    // 是否生成类型声明的 source map(方便调试)
    "declarationMap": true,
    
    // 是否生成 source map 文件(调试时映射到源码)
    "sourceMap": true,
    
    // 是否移除编译后的注释
    "removeComments": false,
    
    // ===== 严格模式(推荐全部开启)=====
    // 启用所有严格类型检查选项(包含下面所有 strict* 选项)
    "strict": true,
    
    // 禁止隐式 any:变量必须有明确的类型
    // ❌ function test(param) {}
    // ✅ function test(param: string) {}
    "noImplicitAny": true,
    
    // 严格空值检查:null 和 undefined 必须显式处理
    // ❌ let name: string = null
    // ✅ let name: string | null = null
    "strictNullChecks": true,
    
    // 严格函数类型检查:函数参数逆变检查
    "strictFunctionTypes": true,
    
    // 严格 bind/call/apply 检查:确保参数类型正确
    "strictBindCallApply": true,
    
    // 严格属性初始化:类属性必须在构造函数中初始化或声明为可选
    "strictPropertyInitialization": true,
    
    // 禁止隐式 this:this 必须有明确的类型
    "noImplicitThis": true,
    
    // 始终以严格模式解析:生成的 JS 代码包含 'use strict'
    "alwaysStrict": true,
    
    // ===== 额外检查 =====
    // 禁止未使用的本地变量(函数内)
    "noUnusedLocals": true,
    
    // 禁止未使用的参数
    "noUnusedParameters": true,
    
    // 禁止隐式返回:函数所有分支都必须有返回值
    "noImplicitReturns": true,
    
    // 禁止 switch 穿透:case 必须有 break 或 return
    "noFallthroughCasesInSwitch": true,
    
    // 索引访问检查:通过索引访问的属性可能为 undefined
    // arr[0] 的类型是 T | undefined
    "noUncheckedIndexedAccess": true,
    
    // 禁止隐式覆盖:子类覆盖父类方法必须使用 override 关键字
    "noImplicitOverride": true,
    
    // 禁止通过索引签名访问属性:强制使用 [] 而非 . 访问动态属性
    "noPropertyAccessFromIndexSignature": true,
    
    // ===== 模块配置 =====
    // ES 模块互操作:允许使用 import foo from 'foo' 导入 CommonJS 模块
    "esModuleInterop": true,
    
    // 允许合成默认导入:没有默认导出的模块也可以 import foo from 'foo'
    "allowSyntheticDefaultImports": true,
    
    // 强制文件名大小写一致:避免跨平台问题
    "forceConsistentCasingInFileNames": true,
    
    // ===== 其他 =====
    // 跳过类型库检查:加快编译速度(不检查 node_modules 中的 .d.ts)
    "skipLibCheck": true,
    
    // 隔离模块:确保每个文件都可以独立编译(适配 Babel、esbuild)
    "isolatedModules": true
  },
  
  // 包含的文件:需要编译的文件路径
  "include": ["src/**/*"],
  
  // 排除的文件:不需要编译的文件路径
  "exclude": ["node_modules", "dist"]
}

# 类型检查最佳实践

// ✅ 推荐:明确的类型注解
function add(a: number, b: number): number {
  return a + b
}

// ❌ 不推荐:隐式 any
function add(a, b) {
  return a + b
}

// ✅ 推荐:接口定义
interface User {
  id: number
  name: string
  email: string
}

function getUser(id: number): User {
  // ...
}

// ✅ 推荐:类型断言(确定时使用)
const input = document.getElementById('input') as HTMLInputElement

// ❌ 不推荐:any 类型
const data: any = fetchData()

// ✅ 推荐:unknown 类型(需要类型检查)
const data: unknown = fetchData()
if (typeof data === 'object' && data !== null) {
  // 使用 data
}

// ✅ 推荐:严格空值检查
function greet(name: string | null): string {
  if (name === null) {
    return 'Hello, Guest'
  }
  return `Hello, ${name}`
}

// ✅ 推荐:可选链和空值合并
const userName = user?.profile?.name ?? 'Anonymous'

# 在构建时进行类型检查

// package.json
{
  "scripts": {
    "type-check": "tsc --noEmit",
    "build": "tsc && vite build"
  }
}

# Vue 项目类型检查

# 安装 vue-tsc
npm install -D vue-tsc
// package.json
{
  "scripts": {
    "type-check": "vue-tsc --noEmit"
  }
}

# 类型声明文件

// src/types/global.d.ts
declare global {
  interface Window {
    customProperty: string
  }
}

export {}
// src/types/api.d.ts
export interface ApiResponse<T> {
  code: number
  message: string
  data: T
}

export interface User {
  id: number
  name: string
  email: string
}

# 五、Stylelint - 样式规范

# Stylelint 简介

Stylelint 是一个强大的现代 CSS 检查工具,帮助你避免错误并强制执行约定。

# 安装

# 基础安装
npm install -D stylelint stylelint-config-standard

# SCSS 支持
npm install -D stylelint-config-standard-scss postcss-scss

# Vue 支持
npm install -D stylelint-config-standard-vue

# Prettier 集成
npm install -D stylelint-config-prettier

# 配置文件

// .stylelintrc.js
module.exports = {
  // 继承的规则集:使用社区维护的规则预设
  extends: [
    'stylelint-config-standard',         // 标准 CSS 规则(需要安装 stylelint-config-standard)
    'stylelint-config-standard-scss',    // SCSS 支持(需要安装 stylelint-config-standard-scss)
    'stylelint-config-standard-vue',     // Vue 单文件组件支持(需要安装 stylelint-config-standard-vue)
    'stylelint-config-prettier'          // 关闭与 Prettier 冲突的规则(需要安装 stylelint-config-prettier)
  ],
  
  // 自定义规则
  rules: {
    // ===== 颜色 =====
    // 颜色十六进制长度:'short' = #fff,'long' = #ffffff
    'color-hex-length': 'short',
    // 禁止使用颜色名称:避免使用 'red'、'blue' 等,统一使用十六进制或 rgb
    'color-named': 'never',
    
    // ===== 字体 =====
    // 字体名称引号:建议在必要时添加引号(如字体名包含空格)
    'font-family-name-quotes': 'always-where-recommended',
    
    // ===== 选择器 =====
    // 类选择器命名规范:使用 camelCase 风格(如 myClass、btnPrimary)
    'selector-class-pattern': '^[a-z][a-zA-Z0-9]*$',
    // ID 选择器命名规范:使用 camelCase 风格
    'selector-id-pattern': '^[a-z][a-zA-Z0-9]*$',
    // 禁止使用 ID 选择器:避免样式权重过高
    'selector-max-id': 0,
    // 通配符选择器最多使用 1 次:限制 * 选择器的使用
    'selector-max-universal': 1,
    
    // ===== 属性 =====
    // 禁止属性使用浏览器前缀:交给 autoprefixer 处理
    'property-no-vendor-prefix': true,
    // 禁止属性值使用浏览器前缀
    'value-no-vendor-prefix': true,
    
    // ===== 声明 =====
    // 禁止使用 !important:避免样式优先级混乱
    'declaration-no-important': true,
    
    // ===== 规则 =====
    // 规则前空行:每个规则前必须有空行(except 表示例外情况)
    'rule-empty-line-before': ['always', {
      except: ['first-nested']  // 嵌套的第一个规则除外
    }],
    
    // ===== 注释 =====
    // 注释前空行:注释前必须有空行
    'comment-empty-line-before': 'always',
    // 注释内部空格:注释符号内必须有空格(/* 内容 */)
    'comment-whitespace-inside': 'always',
    
    // ===== SCSS 特定规则 =====
    // @import 时不需要文件扩展名:@import 'variables' 而非 @import 'variables.scss'
    'scss/at-import-partial-extension': 'never',
    // 禁止未知的 @ 规则:避免拼写错误
    'scss/at-rule-no-unknown': true,
    // SCSS 变量命名规范:使用 camelCase 风格(如 $primaryColor)
    'scss/dollar-variable-pattern': '^[a-z][a-zA-Z0-9]*$',
    
    // ===== 禁用的规则 =====
    // 禁用降序特异性检查:有时后面的规则覆盖前面的规则是合理的
    'no-descending-specificity': null,
    // 允许 Vue 的 :deep、:global 等伪类
    'selector-pseudo-class-no-unknown': [true, {
      ignorePseudoClasses: ['deep', 'global']  // 忽略 Vue 特有的伪类
    }]
  },
  
  // 忽略文件:不对以下文件/目录进行检查
  ignoreFiles: [
    'dist/**/*',         // 构建输出目录
    'node_modules/**/*'  // 依赖包目录
  ]
}

# 使用 Stylelint

# 检查所有样式文件
npx stylelint "**/*.{css,scss,vue}"

# 自动修复
npx stylelint "**/*.{css,scss,vue}" --fix
// package.json
{
  "scripts": {
    "lint:style": "stylelint \"**/*.{css,scss,vue}\"",
    "lint:style:fix": "stylelint \"**/*.{css,scss,vue}\" --fix"
  }
}

# 六、Git Hooks - 提交前检查

# Husky - Git Hooks 管理

# 安装 Husky
npm install -D husky

# 初始化
npx husky init

这会创建 .husky 目录和示例钩子。

# 配置 pre-commit 钩子

# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 运行 lint-staged
npx lint-staged

# 或者运行类型检查
npm run type-check

# lint-staged - 暂存文件检查

只对 Git 暂存区的文件进行检查,提高检查速度。

# 安装
npm install -D lint-staged
// .lintstagedrc.js
module.exports = {
  // JavaScript/TypeScript 文件的检查流程
  // 对 Git 暂存区中的 .js、.jsx、.ts、.tsx 文件执行以下命令
  '*.{js,jsx,ts,tsx}': [
    'eslint --fix',      // 1. 运行 ESLint 并自动修复问题
    'prettier --write'   // 2. 使用 Prettier 格式化代码
  ],
  
  // Vue 文件的检查流程
  // Vue 文件需要同时检查脚本、样式和格式
  '*.vue': [
    'eslint --fix',      // 1. 检查 Vue 文件中的 JavaScript/TypeScript(<script> 部分)
    'stylelint --fix',   // 2. 检查 Vue 文件中的样式(<style> 部分)
    'prettier --write'   // 3. 格式化整个 Vue 文件
  ],
  
  // 样式文件的检查流程
  // 对纯样式文件(.css、.scss、.less)执行检查
  '*.{css,scss,less}': [
    'stylelint --fix',   // 1. 运行 Stylelint 并自动修复样式问题
    'prettier --write'   // 2. 格式化样式代码
  ],
  
  // JSON、Markdown 等文件的格式化
  // 这些文件只需要格式化,不需要 lint 检查
  '*.{json,md}': [
    'prettier --write'   // 使用 Prettier 统一格式
  ],
  
  // TypeScript 类型检查(可选,建议在 CI 中运行)
  // 注意:类型检查会检查整个项目,不仅仅是暂存文件,可能较慢
  '*.{ts,tsx}': [
    () => 'tsc --noEmit'  // 运行 TypeScript 类型检查(不生成文件,只检查类型)
  ]
}

或者使用 package.json:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,vue}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,scss,vue}": [
      "stylelint --fix",
      "prettier --write"
    ]
  }
}

# Commitlint - 提交信息规范

# 安装
npm install -D @commitlint/cli @commitlint/config-conventional
// commitlint.config.js
module.exports = {
  // 继承 Conventional Commits 规范
  // 这是业界广泛使用的提交信息规范(需要安装 @commitlint/config-conventional)
  extends: ['@commitlint/config-conventional'],
  
  // 自定义规则
  rules: {
    // 提交类型枚举:限制允许的提交类型
    // [2, 'always', [...]] 表示:错误级别、何时应用、允许的值
    'type-enum': [2, 'always', [
      'feat',     // 新功能(feature)
      'fix',      // 修复 bug
      'docs',     // 文档更新(documentation)
      'style',    // 代码格式调整(不影响功能,如空格、分号)
      'refactor', // 重构(既不是新功能也不是修复 bug 的代码改动)
      'perf',     // 性能优化(performance)
      'test',     // 测试相关(添加或修改测试)
      'chore',    // 构建过程或辅助工具的变动(如修改构建脚本、更新依赖)
      'revert'    // 回退之前的提交
    ]],
    
    // 类型必须小写
    // 错误: 'Feat: add feature'
    // 正确: 'feat: add feature'
    'type-case': [2, 'always', 'lower-case'],
    
    // 类型不能为空
    // 错误: ': add feature'
    // 正确: 'feat: add feature'
    'type-empty': [2, 'never'],
    
    // 主题(subject)不能为空
    // 错误: 'feat:'
    // 正确: 'feat: add feature'
    'subject-empty': [2, 'never'],
    
    // 主题不能以句号结尾
    // 错误: 'feat: add feature.'
    // 正确: 'feat: add feature'
    'subject-full-stop': [2, 'never', '.'],
    
    // 提交信息标题最大长度:100 个字符
    // 超过会报错,建议保持简洁
    'header-max-length': [2, 'always', 100]
  }
}
# .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit $1

提交信息格式:

<type>(<scope>): <subject>

<body>

<footer>

示例:

feat(auth): add login functionality

- Implement JWT authentication
- Add login form validation
- Create auth store

Closes #123

# 完整的 Git Hooks 配置

# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "🔍 Running pre-commit checks..."

# 运行 lint-staged
npx lint-staged

# 类型检查
echo "🔍 Type checking..."
npm run type-check || {
  echo "❌ Type check failed"
  exit 1
}

echo "✅ Pre-commit checks passed"
# .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "🔍 Validating commit message..."
npx --no -- commitlint --edit $1
# .husky/pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "🔍 Running pre-push checks..."

# 运行测试
npm run test || {
  echo "❌ Tests failed"
  exit 1
}

echo "✅ Pre-push checks passed"

# 七、EditorConfig - 编辑器配置

# 什么是 EditorConfig

EditorConfig 是一个用于统一不同编辑器和 IDE 编码风格的配置文件。它可以让团队成员在使用不同编辑器(如 VS Code、WebStorm、Sublime Text、Vim 等)时保持一致的代码风格。

与 Prettier 的区别:

  • EditorConfig:在编辑器层面生效,实时控制编辑器行为(如按 Tab 键时插入空格)
  • Prettier:代码格式化工具,保存时或手动执行时格式化代码
  • 配合使用:EditorConfig 控制编辑器基础行为,Prettier 负责最终的代码格式化

# 安装

大多数现代编辑器都内置或通过插件支持 EditorConfig:

VS Code:

# 安装 EditorConfig 插件
# 在扩展市场搜索 "EditorConfig for VS Code"

WebStorm / IntelliJ IDEA:

  • 内置支持,无需额外安装

Sublime Text:

# 通过 Package Control 安装 EditorConfig 插件

# 配置文件详解

# .editorconfig

# root = true 表示这是项目的根配置文件,编辑器会停止向上查找其他 .editorconfig 文件
root = true

# [*] 表示对所有文件生效(通配符)
[*]
# 字符编码:使用 UTF-8 编码
# 确保中文、emoji 等字符正确显示
charset = utf-8

# 换行符类型:使用 LF(\n)换行
# lf = Linux/macOS 风格(推荐,Git 默认)
# crlf = Windows 风格(\r\n)
# cr = 旧 macOS 风格(\r)
end_of_line = lf

# 文件末尾插入空行
# true = 文件最后一行是空行(符合 POSIX 标准,某些工具需要)
insert_final_newline = true

# 删除行尾空格
# true = 自动删除每行末尾的空格和 Tab(避免无意义的 diff)
trim_trailing_whitespace = true

# [*.{...}] 表示对特定文件类型生效
# 针对 JavaScript、TypeScript、Vue 文件
[*.{js,jsx,ts,tsx,vue}]
# 缩进风格:使用空格缩进
# space = 空格
# tab = 制表符(Tab)
indent_style = space

# 缩进大小:2 个空格
# 也可以设置为 4(根据团队习惯)
indent_size = 2

# 针对样式文件
[*.{css,scss,less}]
indent_style = space
indent_size = 2

# 针对配置文件
[*.{json,yml,yaml}]
indent_style = space
indent_size = 2

# 针对 Markdown 文件
[*.md]
# Markdown 中行尾空格有特殊含义(两个空格表示换行)
# 所以不删除行尾空格
trim_trailing_whitespace = false

# 针对 Makefile
# Makefile 必须使用 Tab 缩进(语法要求)
[Makefile]
indent_style = tab

# 支持的配置选项

EditorConfig 支持以下常用配置项:

配置项 说明 可选值
indent_style 缩进风格 space(空格)、tab(制表符)
indent_size 缩进大小 数字(如 2、4)
tab_width Tab 字符显示宽度 数字(默认与 indent_size 相同)
end_of_line 换行符类型 lf、crlf、cr
charset 字符编码 utf-8、utf-16be、utf-16le、latin1
trim_trailing_whitespace 删除行尾空格 true、false
insert_final_newline 文件末尾插入空行 true、false
max_line_length 最大行长度 数字或 off

# 最佳实践

  1. 项目初期就创建 .editorconfig

    • 避免后期大量修改缩进、换行符等带来的 diff 混乱
  2. 保持简洁

    • 只配置必要的选项(缩进、换行符、编码)
    • 其他复杂规则交给 Prettier 和 ESLint
  3. 与团队达成一致

    • EditorConfig 配置应该是团队共识
    • 不要随意修改已有配置(会影响整个代码库)
  4. 提交到版本控制

    git add .editorconfig
    git commit -m "chore: add EditorConfig"
    
  5. 在 README 中说明

    ## 开发环境配置
    
    本项目使用 EditorConfig 统一编码风格,请确保你的编辑器已安装 EditorConfig 插件:
    
    - **VS Code**: 安装 "EditorConfig for VS Code" 扩展
    - **WebStorm**: 内置支持,无需安装
    - **Sublime Text**: 通过 Package Control 安装 EditorConfig 插件
    

# 八、编辑器集成

# VS Code 配置

# 推荐插件

// .vscode/extensions.json
{
  "recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "stylelint.vscode-stylelint",
    "editorconfig.editorconfig",
    "vue.volar"
  ]
}

# 工作区配置

// .vscode/settings.json
{
  // ===== 编辑器 =====
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.fixAll.stylelint": "explicit"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  
  // ===== ESLint =====
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "vue"
  ],
  "eslint.codeActionsOnSave.rules": null,
  
  // ===== Stylelint =====
  "stylelint.validate": [
    "css",
    "scss",
    "vue"
  ],
  "css.validate": false,
  "scss.validate": false,
  
  // ===== Prettier =====
  "prettier.enable": true,
  "prettier.requireConfig": true,
  
  // ===== 文件关联 =====
  "files.associations": {
    "*.css": "css",
    "*.scss": "scss"
  },
  
  // ===== Vue =====
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  
  // ===== TypeScript =====
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

# WebStorm / IntelliJ IDEA 配置

  1. 启用 ESLint:

    • Settings → Languages & Frameworks → JavaScript → Code Quality Tools → ESLint
    • 勾选 Automatic ESLint configuration
    • 勾选 Run eslint --fix on save
  2. 启用 Prettier:

    • Settings → Languages & Frameworks → JavaScript → Prettier
    • 设置 Prettier 包路径
    • 勾选 On save
  3. 启用 Stylelint:

    • Settings → Languages & Frameworks → Style Sheets → Stylelint
    • 勾选 Enable

# 九、CI/CD 集成

# GitHub Actions

# .github/workflows/lint.yml
name: Lint

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  lint:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run ESLint
        run: npm run lint
      
      - name: Run Prettier check
        run: npm run format:check
      
      - name: Run Stylelint
        run: npm run lint:style
      
      - name: Type check
        run: npm run type-check
      
      - name: Run tests
        run: npm run test

# GitLab CI

# .gitlab-ci.yml
stages:
  - lint
  - test

lint:
  stage: lint
  image: node:18
  cache:
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run lint
    - npm run format:check
    - npm run lint:style
    - npm run type-check
  only:
    - merge_requests
    - main

# 十、最佳实践总结

# 1. 渐进式采用

# 第一步:基础配置
npm install -D eslint prettier

# 第二步:框架支持
npm install -D eslint-plugin-vue

# 第三步:TypeScript
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

# 第四步:样式检查
npm install -D stylelint

# 第五步:Git Hooks
npm install -D husky lint-staged

# 2. 团队规范

  • 统一配置:将所有配置文件提交到代码仓库
  • 文档化:在 README 中说明如何使用
  • CI 检查:在 CI/CD 中强制执行检查
  • 定期更新:保持工具和规则的更新

# 3. 性能优化

  • 使用 .eslintignore 和 .prettierignore 排除不需要检查的文件
  • lint-staged 只检查暂存文件
  • 避免在 Git Hooks 中运行耗时的全局类型检查
  • 使用缓存加速 ESLint(--cache 选项)

# 4. 规则制定

  • 从宽松到严格:初期使用 warn,逐步改为 error
  • 团队协商:规则应由团队共同决定
  • 持续改进:根据实际情况调整规则
  • 有理有据:每条自定义规则都应有明确的原因

# 5. 工具选择

场景 推荐工具
代码规范 ESLint
代码格式化 Prettier
类型检查 TypeScript
样式规范 Stylelint
提交规范 Commitlint
Git Hooks Husky + lint-staged

# 十一、学习资源

# 官方文档

  • ESLint 官方文档 (opens new window)
  • Prettier 官方文档 (opens new window)
  • TypeScript 官方文档 (opens new window)
  • Stylelint 官方文档 (opens new window)
  • Husky 官方文档 (opens new window)

# 推荐资源

  • Awesome ESLint (opens new window)
  • ESLint 规则速查 (opens new window)
  • TypeScript ESLint (opens new window)
  • Airbnb JavaScript Style Guide (opens new window)

# 相关文章

  • TypeScript极简入门
  • Vite极简入门
  • Vue.js快速入门

祝你变得更强!

编辑 (opens new window)
#ESLint#Prettier#TypeScript#代码规范#前端工程化
上次更新: 2025/11/17
Vite极简入门
HTML基础全景图

← Vite极简入门 HTML基础全景图→

最近更新
01
AI编程时代的一些心得
09-11
02
Claude Code与Codex的协同工作
09-01
03
Claude Code 最佳实践(个人版)
08-01
更多文章>
Theme by Vdoing | Copyright © 2018-2025 京ICP备2021021832号-2 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式