【前端工程化】前端代码规范与静态检查

在团队协作开发中,统一的代码规范能显著降低沟通成本,提高团队协作效率,减少因代码风格差异导致的错误。

静态检查工具则通过自动化手段提前发现潜在问题,如语法错误、潜在逻辑缺陷,帮助开发者遵循代码最佳实践,在研发过程中尽早发现和改正问题,从而规避线上事故,提升代码质量和可维护性。

背景问题

  1. 团队内代码规范缺乏或覆盖不全
  2. 代码规范依靠自觉或人工审查,难以有效落实
  3. 常见代码错误导致线上问题频发,e.g.
    1. 没有对变量进行类型检查,导致运行时错误(可使用ESLint的@typescript-eslint/no-explicit-any进行静态检查以规避)
    2. 意外修改函数入参,导致在后续逻辑中引入副作用(可使用ESLint的no-param-reassign进行静态检查以规避)

前端代码规范

以下列举一些常见的代码规范作为示例。

基础语法规范

对应Prettier代码格式化。

  • 缩进与换行:使用 2 个空格缩进(避免制表符),单行代码长度建议不超过 80-120 个字符,超过时合理换行
  • 命名规范:采用驼峰命名法,变量名见名知义。例如:userInfofetchUserData;常量全大写,如MAX_COUNT
  • 分号使用:建议在语句末尾显式添加分号,避免因自动分号插入(ASI)规则引发的潜在问题

HTML 规范

  • 语义化标签:优先使用<header><nav><main>等语义化标签,提升可访问性和 SEO
  • 属性顺序:按照classidsrchrefalt等逻辑顺序排列标签属性
  • 闭合标签:确保所有标签正确闭合,如<img>需写成<img src="" alt="" />;嵌套正确,标签名小写。

CSS 规范

对应StyleLint静态检查。

  • 选择器命名:采用 BEM 命名规范(e.g. block__element--modifier)或其他规范。
  • 属性声明顺序:按照盒模型逻辑分组(推荐)或字母表顺序。
  • 避免!important:仅在极特殊场景使用,防止样式覆盖冲突。

BEM 规范

详细参考:BEM --- Block Element Modifier

以采用 BEM 规范的 Vue 基础表单组件为例:

jsx 复制代码
<template>
  <form class="form form--search">
    <div class="form__group">
      <label class="form__label">搜索:</label>
      <input class="form__input form__input--large" type="text" />
      <button class="form__button form__button--primary">提交</button>
    </div>
  </form>
</template>
<style lang="scss">
  .form {
    &__group {
    }

    &__label {
    }

    &__input {
      &--large {
      }
    }

    &__button {
      &--primary {
      }
    }
  }
</style>

BEM 将页面组件拆分为三个基本概念:

  1. Block(块)

    1. 独立的实体,具有语义化名称(如headerbuttonform)。

    2. 块名使用小写字母或数字,多个单词用连字符()连接。

      jsx 复制代码
      <div class="header"></div>
      <button class="button"></button>
  2. Element(元素)

    1. 块的组成部分,依赖于块存在(如header__logobutton__text)。

    2. 元素名由块名加双下划线(__)和元素名称组成。

      xml 复制代码
      <div class="header">
        <div class="header__logo"></div> <!-- 元素 -->
        <nav class="header__nav"></nav>   <!-- 元素 -->
      </div>
  3. Modifier(修饰符)

    1. 表示块或元素的状态、变体(如button--primarybutton--disabled)。

    2. 修饰符名由块 / 元素名加双连字符(-)和修饰符名称组成。

      xml 复制代码
      <button class="    button button--primary"> <!-- 块+修饰符 -->
        <span class="button__text button__text--bold"></span> <!-- 元素+修饰符 -->
      </button>

BEM 的优势:

  1. 明确的结构
    类名直观反映组件层级关系,如header__nav__item清晰展示嵌套结构。
  2. 避免样式冲突:全局唯一的类名(如block__element--modifier)杜绝了 CSS 选择器的层级依赖,减少样式覆盖。
  3. 高可维护性:代码结构清晰,新人可快速理解组件组成,修改时不易影响其他部分。
  4. 组件复用:块级独立的设计便于组件在不同场景复用。

BEM 适用场景:

  1. 大型项目:当项目规模庞大、团队成员众多时,BEM 能有效规范命名,降低协作成本。
  2. 组件化开发:在 React、Vue 等框架中,BEM 与组件化思想高度契合,每个组件可视为一个块。
  3. 长期维护的项目:清晰的命名和结构使代码更易维护和扩展,适合生命周期较长的项目。

BEM 规范的静态检查工具:

StyleLintstylelint-selector-bem-pattern插件,可以检查 BEM 命名规则。

CSS 属性声明顺序

建议按布局 → 盒模型 → 视觉表现 → 交互与动画排序

  1. 布局属性:display, position, top/right/bottom/left, float, clear, flex, grid
  2. 盒模型属性:width, height, margin, padding, border, box-sizing
  3. 视觉表现:background, color, font, text-align, opacity, overflow
  4. 交互与动画:cursor, transition, animation, transform

CSS 属性声明顺序的静态检查工具 :通过 StyleLint 的stylelint-order插件强制执行属性排序规则。

JavaScript 规范

详细参考: Airbnb JavaScript 规范Google 风格指南

对应 ESLint 静态检查。

  • 严格模式:在文件顶部添加'use strict';,启用严格模式,避免意外全局变量和语法错误
  • 模块化:优先使用 ES6 模块(import/export),避免 CommonJS 或 AMD 规范的混用
  • 箭头函数:简洁场景使用箭头函数,但需注意this指向,复杂逻辑仍使用普通函数
  • 禁止 var:统一使用 const 和 let,优先 const。
  • 等号使用:统一使用严格相等 ===/!==,禁止 ==/!=

Vue 规范

详细参考:Vue.js 风格指南

  • 组件命名:使用多单词且采用 PascalCase 或 kebab-case,多个单词组成的名称应清晰体现组件功能。
  • 变量和方法命名:使用小驼峰命名法,遵循语义化原则,如dataVariable、handleClick。
  • 组件书写顺序:按照执行先后顺序和重要性来依次排列各个模块、变量和函数。
  • 模板结构:模板中元素应按逻辑分组,使用注释分隔不同功能部分,如 、 、 。

Vue 组件书写顺序

  • 标签顺序:单文件组件应始终对 <script><template><style> 标签进行排序,<style> 排在最后,因为其他两个标签中至少有一个总是必要的。
  • 变量和函数顺序:<script> 内部按照name、props、setup(如果是组合式API)、data(如果是选项式API)、生命周期钩子(按照执行的先后顺序排序)、methods、computed、watch的顺序排列。

Vue 组件书写顺序的静态检查工具:

json 复制代码
// options 语法默认排序
"el",
"name",
"key",
"parent",
"functional",
["delimiters", "comments"],
["components", "directives", "filters"],
"extends",
"mixins",
["provide", "inject"],
"ROUTER_GUARDS",
"layout",
"middleware",
"validate",
"scrollToTop",
"transition",
"loading",
"inheritAttrs",
"model",
["props", "propsData"],
"emits",
"slots",
"expose",
"setup",
"asyncData",
"data",
"fetch",
"head",
"computed",
"watch",
"watchQuery",
"LIFECYCLE_HOOKS",
"methods",
["template", "render"],
"renderError"

// setup 语法默认排序
"type",
"defineProps",
"defineEmits",
"defineSlots",
"defineModel",
"defineOptions",
"class",
"plainVars",
"reactiveVars",
"composables",
"computed",
"watchers",
"lifecycle",
"unknowns",
"functions",
"defineExpose"

React 规范

详细参考:Rules of ReactAirbnb React/JSX Style Guide

  • 组件命名:组件名为大驼峰命名法(PascalCase),且组件名称与文件名称保持相同。高阶组件使用小驼峰命名法(camelCase),建议使用withXxx或xxxable形式的词作为高阶组件的名称。
  • 属性命名:props中用于回调的属性名称使用onXxx形式。作为组件方法的事件处理函数以具备业务含义的词作为名称,不使用onXxx形式命名。
  • 组件属性声明:所有组件均需声明propTypes。对于非isRequired的属性,在defaultProps中声明对应的值。使用静态属性语法声明propTypes、contextTypes、defaultProps和state。
  • JSX标签书写:在自闭合的标签中仅使用单空格。当JSX包含多行代码时,将它们包含在小括号中。
  • 方法命名:对于React组件的内部方法,不要使用下划线作为前缀。
  • 方法顺序:React.Component子类中方法顺序为constructor、可选静态方法、getChildContext、生命周期方法、事件处理函数、渲染相关的获取方法、可选的渲染方法、render方法。

代码提交规范

在Git Commit Message增加提交类型(fix、feat、test等)和作用域(模块、接口、类等),将使代码审查人员清晰地了解当前提交的目的和范围。

详见约定式提交规范

总结

从以上可以看出,前端代码规范主要包含以下几个层面:

  1. 语法规范
    1. 规定代码的书写格式,如缩进、换行、引号使用等。
    2. 明确变量、函数、类等的命名规则。
  2. 代码结构规范
    1. 确定项目的文件组织方式,如如何划分模块、组件,以及不同类型文件的存放位置。
    2. 规定组件或模块内部的代码结构,如React或Vue组件中各个选项(props、data、methods等)、import的书写顺序。
  3. 命名规范
    1. 统一目录名、文件名、组件名、属性名、CSS选择器等的命名方式。
  4. 逻辑规范
    1. 对代码中的逻辑流程进行规范,如避免过度嵌套的条件判断和循环,确保代码的可读性和可维护性。
    2. 规定数据处理和交互的方式,包括组件间通信、事件处理等。

代码规范的执行,除了借助于文档说明、人工代码审查以外,通过静态检查更能有效地落实。

前端静态检查工具

静态检查可介入的研发阶段

  1. 编写代码时,通过开发工具进行代码自动补全,实时高亮提示代码错误和警告
  2. 保存文件时,自动进行格式化,按照 Lint 规则进行自动纠正
  3. 提交代码前,通过 Git Hooks 拦截进行 代码Lint 检查和提交日志检查
  4. 在代码审查和在CI/CD管道构建时,执行代码 Lint 检查

前端常用 Lint 工具

  • 代码Lint工具:
    • ESLint: JavaScript 代码检查工具。
    • StyleLint: CSS/Sass/Less/ PostCSS/Vue 的

Git Hooks

使用Git Hooks脚本,及时发现问题,在改正之前不允许提交代码。

  • 规范代码: 统一代码风格,提高可读性。
  • 规避错误: 及早发现潜在问题,减少 bug。
  • 规范提交:统一提交规则,格式化提交信息。
  • 自定义 Lint 规则:根据项目需求,定制 Lint 规则,确保代码符合团队规范。

使用Git Hooks脚本介入的阶段:

  1. pre-commit阶段:使用 lint-staged对暂存文件运行 Lint 和格式化。
  2. commit-msg阶段:确保提交消息遵循规范的提交格式。
  3. pre-push阶段:可对受影响的项目运行自动化测试用例。

Git Hooks配置工具:

  • Simple-Git-Hooks / Husky:在 Git hooks 中集成 lint 命令,每次提交前自动执行 lint 检查,确保 lint 结果通过才能提交代码。
  • Lint-Staged:只对暂存区的改动文件执行 lint,而非全量代码,提高效率。针对不同的文件类型配置不同的 lint 规则,默认情况会并行执行。

VS Code 插件

VS Code 插件可帮助大家在保存代码时即可执行自动Lint检查和格式化,尽早提前发现问题。

前端静态检查配置

工程配置阶段

配置步骤

此处依赖安装工具以yarn为例,仓库为monorepo工程,同时包含 React 和 Vue 子工程。

操作步骤:

  1. 安装Lint依赖:在仓库根目录执行以下命令:

    复制代码
    // commitlint相关
    yarn add -D -W simple-git-hooks lint-staged @commitlint/cli @commitlint/config-conventional commitizen
    
    // eslint相关
    yarn add -D -W eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-vue eslint-plugin-react eslint-plugin-react-hooks eslint-config-prettier eslint-plugin-prettier eslint-plugin-node eslint-plugin-import eslint-import-resolver-typescript eslint-vue-setup-order
    
    // stylelint相关
    yarn add -D -W stylelint stylelint-prettier stylelint-config-standard-scss stylelint-config-standard-less postcss-html stylelint-config-standard-vue stylelint-order stylelint-config-property-sort-order-smacss
    
    // prettier
    yarn add -D -W prettier prettier-plugin-packagejson prettier-plugin-organize-imports prettier-plugin-tailwindcss
    
    // tsc-files
    yarn add -D -W tsc-files
  2. 配置Lint规则 :在 monorepo 工程根目录的 package.json 中配置 simple-git-hooks 和 lint-staged,以在执行yarn install时配置相关 git hooks,并在后续提交代码时自动执行代码Lint和Commit Message Lint检查。

    复制代码
    // package.json
    "scripts": {
      "prepare": "simple-git-hooks"
    },
    "simple-git-hooks": {
        "commit-msg": "npx --no -- commitlint --edit $1",
        "pre-commit": "npx lint-staged"
    },
    "lint-staged": {
        "*.{js,jsx,ts,tsx,vue}": [
          "eslint --fix",
          "prettier --write"
        ],
        "*.{css,scss,less,vue}": [
          "stylelint --fix",
          "prettier --write"
        ],
        "*.ts": [
          "tsc-files --noEmit" // 只检查类型,不生成输出。 这里不能使用tsc,否则会忽略tsconfig.json文件规则
        ]
    }
  3. 工作区配置

    1. 在项目根目录的 package.json 中,通过 "workspaces" 字段来定义子工程所在的目录。由于工作区机制,子工程在执行 yarn install时会向上查找根目录的配置并安装 lint 规则检查等相关依赖。

    2. 在子工程的 package.json 中添加脚本,通过相对路径调用根目录的 prepare 脚本,触发根目录配置好的git hooks 相关配置脚本。

      // root
      {
      "private": true,
      "workspaces": [
      "packages/*"
      ]
      }

      // child project
      {
      "scripts": {
      "postinstall": "cd ../.. && yarn prepare"
      }
      }

Lint 规则

由于代码仓库使用了monorepo方式来管理和组织代码,故需要整合各个子工程中的Lint配置。

  • 优先使用子工程中的配置,如果没有则使用根目录中的配置。

  • 根目录中会保留一个基础的公共配置,然后每个子工程中的配置文件可以继承这个基础配置,并根据自身需求进行扩展或覆盖。

  • 相关配置文件格式

    • .prettierrc.js

    • .eslintrc.js: ESLint 新一代"平铺配置"(Flat Config)的规则参考:https://blog.csdn.net/Bruce__taotao/article/details/148780430。

    • tsconfig.json

    • .stylelintrc.js

      // 配置示例:

      // .eslintrc.json
      {
      "extends": ["eslint:recommended", "plugin:react/recommended"],
      "rules": {
      "no-global-assign": "error", // 禁止给全局变量赋值
      "no-undef": "error", // 禁止使用未定义的变量
      "no-unused-vars": "error", // 禁止使用未声明过的变量
      "prefer-const": "error", // 鼓励使用const声明变量
      "strict": "error" // 启用严格模式,捕获更多错误
      }
      }

      // .prettierrc.json
      {
      "semi": false,
      "singleQuote": true,
      "trailingComma": "all"
      }

      // .stylelintrc.json
      {
      "extends": ["stylelint-config-standard", "stylelint-config-prettier", "stylelint-config-standard-scss", "stylelint-config-prettier-scss"],
      "rules": {
      // ...
      }
      }

      // tsconfig.json
      {
      "compilerOptions": {
      "target": "es6",
      "module": "commonjs",
      // ...
      }
      }

Commit Message 规则

  • 按照Git提交记录语义化规范,在提交代码前检查提交信息是否规范 。主要验证commit message中 scope 和 type 是否符合规定。
    • 安装commitlintcommitizen,用于执行:yarn add -D -W @commitlint/cli @commitlint/config-conventional commitizen

    • package.json中添加git hooks配置,以在git commit时确保提交信息的规范性:"commit-msg": "npx --no -- commitlint --edit $1"

    • package.json中添加命令,供个人提交代码时进行书写提示:"commit": "cz"

    • 在根目录中添加commitlint.config.js文件

      c 复制代码
      // commitlint.config.js
      // 配置示例:
      
      export default {
        extends: ["@commitlint/config-conventional"],
        rules: {
          /**
           * scope-enum 提交scope的枚举
           * docs: 文档 docs
           * pc: PC端应用代码
           * mobile: 移动端应用代码
           * public: PC端和移动端共用代码
           * laf: 后端laf-cloud接口
           * desktop: 桌面端应用代码
           * scripts: 项目脚本 scripts
           */
          "scope-enum": [2, "always", ["docs", "pc", "mobile", "public", "laf", "desktop", "scripts"]],
          "type-enum": [
            2,
            "always",
            [
              "feat",
              "fix",
              "style",
              "docs",
              "perf",
              "test",
              "refactor",
              "chore",
              "revert",
              "build",
              "ci",
            ],
          ],
          "type-case": [0],
          "subject-empty": [0],
          "type-empty": [0],
          "scope-empty": [0],
          "scope-case": [0],
          "subject-full-stop": [0],
          "subject-case": [0],
          "header-max-length": [0],
        },
      };

VS Code 配置

为了保证团队所有成员的开发配置的一致性,增加Workspace的VS Code配置,并将文件随代码提交到 Git 仓库,后续可持续更新。

  • extensions配置

    • 在代码工程的根目录下新增 .vscode/extensions.json文件,用于注册插件列表。

      json 复制代码
      // .vscode/extensions.json
      {
        // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
        // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
      
        // List of extensions which should be recommended for users of this workspace.
        "recommendations": [
          "nrwl.angular-console",
          "stylelint.vscode-stylelint",
          "esbenp.prettier-vscode",
          "dbaeumer.vscode-eslint",
          "antfu.unocss",
          "usernamehw.errorlens",
          "streetsidesoftware.code-spell-checker"
        ],
        // List of extensions recommended by VS Code that should not be recommended for users of this workspace.
        "unwantedRecommendations": []
      }
    • 后续如果团队内成员发现了好用的插件,可动态补充到上述代码中的 recommendations 数组中。

    • 每次打开代码工程时,VS Code会自动检查并推荐没安装的vs code插件,可点击一键安装。

  • settings配置

    • 在代码工程的根目录下新增 .vscode/settings.json文件,用于记录并同步VS Code插件相关配置信息,e.g. 保存文件时自动格式化、保存文件时针对指定的文件格式自动执行Lint检查。

      // .vscode/settings.json
      {
      "editor.codeActionsOnSave": {
      "source.fixAll.eslint": "explicit",
      "source.fixAll.stylelint": "explicit"
      },
      "eslint.format.enable": true,
      "eslint.validate": [
      "javascript",
      "javascriptreact",
      "vue",
      "typescript",
      "typescriptreact",
      "html"
      ],
      "stylelint.validate": ["css", "less", "scss", "postcss", "html", "vue", "svelte", "astro"],
      "css.validate": false,
      "less.validate": false,
      "scss.validate": false,
      "editor.defaultFormatter": "esbenp.prettier-vscode",
      "editor.formatOnSave": true,
      "prettier.requireConfig": true
      }

日常开发阶段

保存文件

保存文件时,VS Code会自动使用Prettier、ESLint、StyleLint等规则来格式化代码,纠正相关 Lint 错误。

提交代码

  1. 每次使用git commit -m *或使用其他类似达到同样功能的操作时,都会自动执行上述git hooks。
    1. 检查Commit Message是否规范。可借助上述提到的git semantic commits脚本或cz命令来简化提交操作。
    2. 检查代码是否存在问题
  2. 如果发现问题,会禁止commit。

修改问题

  1. 对于大多数错误,需要进行修改。
  2. 对于有意为之的代码,添加 Lint 忽略规则。

建议在提交代码时,将单个完整的 feature 或 fix 作为一个单独的commit,这样生成changelog时会作为单行记录。如果单个 feature 或 fix 包含多个commit,则可将其squash合并为单个commit。

前端静态检查注意事项

引入静态检查时的注意事项

  • 遗留问题:如果遗留代码的问题较多,无法统一修改,可逐步扩大静态检查的范围,在日常开发中逐渐发现和改正。
  • Git Hooks Lint范围:由于git commit时的Lint检查是针对改动过的文件进行检查,后续开发时需要将所有改动过的文件中的遗留Lint错误进行逐一改正后才能顺利提交代码。因此,即使只修改其中几行,Lint 工具也可能检测出当前文件中未改动的其他多处错误,这时需要依赖大家把之前的错误改正后再提交。
  • 可持续改进:根据团队反馈定期更新规则、补充示例。如果发现当前工程配置的 Lint 规则设置不合理,或者导致了过多无用修改,可添加或者自定义更多 Lint 规则以规避。

静态检查的局限性

虽然静态检查工具可以帮助保证部分代码规范的落地,如通过ESLint检查语法错误、代码风格是否符合约定,通过StyleLint检查CSS样式规范等,但并不是所有层面的规范都能通过静态检查来保证。

  • 业务逻辑的规范:如数据处理的合理性、组件交互逻辑的正确性等,静态检查工具难以完全覆盖。
  • 架构设计的规范:代码的整体架构设计和一些高层次的设计决策无法通过静态检查来验证是否符合规范。

因此,除了静态检查工具外,还需要通过代码审查、制定详细的开发文档和规范指南,并加强团队成员的培训和沟通来确保前端代码规范的全面落地。

Lint 规则帮助文档

在后续开发中,遇到Lint错误,可通过如下文档搜索对应规则,以查看错误示例和正确示例。

Lint 绕行方法

以下方法的屏蔽范围依次递增,根据需要选用其中一个:

  1. 针对单行 / 单个文件 进行屏蔽:极端情况下使用,适用于通过修改代码很难规避lint错误的情况。在VS Code中右键提示错误的代码行位置,会出现Quick Fix修改帮助提示,如下图。
  2. 针对文件、目录或子工程进行屏蔽
    1. ESLint:在ESLint配置文件(e.g. eslint.config.js)的ignores配置中添加忽略目录或文件
    2. StyleLint:在.stylelintignore文件中添加忽略目录或文件
    3. TypeScript:在对应的子工程目录的tsconfig.json文件的exclude字段中添加忽略目录或文件
    4. Prettier:在.prettierignore文件中添加忽略目录或文件

写在最后

在开发实践中充分使用静态检查工具,让编码工作既高效流畅,又能产出高质量的代码成果。

相关推荐
C2X2 小时前
关于Git Graph展示图的理解
前端·git
昊茜Claire2 小时前
鸿蒙开发之:性能优化与调试技巧
前端
雲墨款哥2 小时前
从一行好奇的代码说起:Vue怎么没有React的<StrictMode/>
前端
小肥宅仙女2 小时前
告别繁琐!React 19 新特性对比:代码量减少 50%,异步状态从此自动管理
前端·react.js
ohyeah2 小时前
柯理化(Currying):让函数参数一个一个传递
前端·javascript
9坐会得自创3 小时前
使用marked将markdown渲染成HTML的基本操作
java·前端·html
Hilaku3 小时前
当 Gemini 3 能写出完美 CSS 时,前端工程师剩下的核心竞争力是什么?
前端·javascript·ai编程
最贪吃的虎3 小时前
什么是开源?小白如何快速学会开源协作流程并参与项目
java·前端·后端·开源
裴嘉靖3 小时前
Vue + ECharts 实现图表导出为图片功能详解
前端·vue.js·echarts