前端编码规范

1. 目的

统一团队编码风格,汇集团队最佳编码实践经验,增强代码可读性和可维护性,进而提高团队协作和开发效率以及代码质量。


2. 原则

  • ✅ 符合 W3C 标准
  • ✅ 语义化,结构、表现、行为分离
  • ✅ 代码质量、性能和兼容性优良

3. 公共规范

3.1 目录和文件命名

  • 【强制】目录和文件名不能以数字开头,语义化命名
  • 【强制】非特殊情况,目录和文件名默认采用 kebab-case 方式,即以全小写字母加 - 连接(新项目强制执行,旧项目根据情况尽量遵守)
  • 内容有复数结构时,采用复数形式命名,如 utilsstyles

3.2 代码格式

  • 【强制】缩进使用 2 个空格或软 tab 设置为 2 个空格
  • 代码片段、变量和符号间留适当空格

3.3 文件编码

  • 【强制】使用无 BOM 的 UTF-8 编码

3.4 外联资源引入

  • 【强制】站内外联资源用相对路径引入
  • 【强制】站外外联资源用 https 协议的全路径引入

4. HTML 规范

  • 【强制】按语义化使用标签,如:headerfooter

  • 【强制】标签嵌套规范

    • 内联元素不要包含块级元素
    • p 标签不要包含块级元素
    • a 标签非特殊情况避免嵌套
  • 【强制】imginputbr 等标签不需要闭合

  • 【强制】减少不必要的标签数量,避免过度嵌套

  • 【强制】同一元素类名不超过 5 个

  • 尽量避免在元素上写 style

  • 重要图片必须加上 alt 属性

  • 给重要的元素和截断的元素加上 title

  • html 加上 lang 属性

  • HTML 模板加上声明:

    html 复制代码
    <!DOCTYPE html>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  • HTML 标签分类参考: html标签分类


5. CSS 规范

5.1 命名规范

  • 【强制】命名规范:
    • 由小写字母、-、数字组成
    • 语义化命名
    • 模块化前缀:全局(系统名,非必要)-模块(模块名)-组件
    • 举例:fbs-inbound-request-dialog

5.2 词汇规范

  • 推荐根据内容、功能来命名,不依据表现形式来命名
    • ✅ 推荐:navasidenewstypesearch
    • ❌ 不推荐:leftrighttop### 5.3 属性顺序
  1. Position

    css 复制代码
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 100;
  2. Box model

    css 复制代码
    display: block;
    float: right;
    width: 100px;
    height: 100px;
  3. Typographic

    css 复制代码
    font: normal 13px "Helvetica Neue", sans-serif;
    line-height: 1.5;
    color: #333;
    text-align: center;
  4. Visual

    css 复制代码
    background-color: #f5f5f5;
    border: 1px solid #e5e5e5;
    border-radius: 3px;
  5. Misc

    css 复制代码
    opacity: 1;

5.4 其他规范

  • 超过 2 个同类属性使用缩写,比如:marginpaddingfont
  • 0 不带单位,除非是 deg 等特殊单位
  • 小数不带 0

5.5 布局特性

充分了解并使用布局特性,减少不必要或无效的属性声明:

  • display: inline 后不应该再使用 widthheightmargin 上下、padding 以及 float
  • display: inline-block 后不应该再使用 float
  • display: block 后不应该再使用 vertical-align
  • display: table-* 后不应该再使用 margin 或者 float
  • 合理使用 BFC 来解决 margin 重叠、清除浮动等

5.6 性能优化

  • 减少不必要的嵌套,不超过 3 级嵌套
  • 选择器使用优先级(CSS 树是从下往上,选择器从右往左匹配):
    1. 类选择器(.myclassname
    2. 标签选择器(divh1p
    3. 相邻选择器(h1+p
    4. 子选择器(ul > li
    5. 后代选择器(li a
    6. 通配符选择器(*
    7. 属性选择器(a[rel="external"]
    8. 伪类选择器(a:hoverli:nth-child
  • 【强制】禁止 id 选择器用于样式声明
  • 尽量使用属性继承:
    • 字体系列:font
    • a 标签字体颜色不能被继承
    • 文本系列:text-alignline-heightcolor
    • table 属性:caption-sideborder-collapseempty-cells
    • list 属性:list-style
  • 尽量避免使用高性能消耗的 CSS 属性:
    • gradient
    • filter
    • box-shadow
    • !important
  • 尽量避免重排重绘

6. JS 规范

6.1 命名规范

  • 【强制】命名规范:
    • 变量名使用小驼峰命名,首字母小写
    • 类名采用驼峰命名法,首字母大写
    • 常量采用蛇形命名法,大写加 _ 分割
    • 与后台对接字段可遵循后台规范,使用全小写加 _ 分割,减少不必要的转换
    • boolean 类型的变量使用 ishascan 开头
  • 【推荐】拼写能够表明含义,除了业界常用名词外使用英文拼写

6.2 代码格式

  • 【强制】语句结束必须加分号
  • 【强制】使用 TypeScript 进行开发

6.3 注释规范

  • 适当的注释:特殊业务、复杂逻辑等写明处理
  • 注释建议英文,可以使用中文
  • 函数内使用单行注释,多行时可使用多个单行 //
  • 文档注释参考规范:JSDoc
  • 尽量使用单行注释或多个单行注释
  • 建议使用 TODO

6.4 函数规范

  • 【建议】长度标准:小于 50 行,复杂功能尽量抽出来
  • 最小函数准则,职责单一
  • 参数标准:小于 4,超出尽量使用 options
  • 函数命名需要语义化
    • ✅ 推荐:getClientID
    • ❌ 不推荐:idFun

6.5 变量规范

  • 变量声明放置顶端,在 JS 中即使放置于中间也会被提前
  • 【强制】禁止使用 var,如有必要全局变量可用 window.xxx 声明
  • 使用明确的类型赋值和判断,比如使用 !!true/false===isArray
  • 【强制】不要扩充内置或第三方原型,比如:ArrayString

6.6 性能优化

  • 避免不必要的 DOM 查询或操作次数,可以缓存变量
  • 如有必要尽量使用 id 作为 JS 选择器

6.7 异常处理

  • 【强制】所有的异常情况都需要处理
  • await 需使用 try catch 捕获异常,按需抛出新的 Error
  • 避免内存泄漏

6.8 其他规范

  • 不要使用魔法数字
  • 不相信任何外部输入,必须做容错判断
  • 自测必须覆盖每一行代码,每一个逻辑分支
  • 中途变更实现后,必须重新确认全部 checklist
  • 提交前必须检查代码:整理代码思路是否清晰,去除调试代码
  • 所有代码都应该有功能边界,职责明确
  • 组件和模块间交互输入输出明确且收敛,避免依赖发散,如:减少 $refs 操作,避免 store 直接修改等
  • 【建议】代码重复不超过 2 遍
  • 函数或者后台接口输入输出保持最少字段原则

6.9 模块引入顺序

模块引入顺序应如:

  1. 外部模块
  2. 空行
  3. 内部模块
  4. 空行
  5. 外部组件
  6. 空行
  7. 内部组件
  8. 空行
  9. CSS 相关

7. 框架使用规范

7.1 Vue

7.1.1 Vue 项目文件目录及命名
复制代码
api          # 所有后台接口声明
assets       # 所有icon、图片等可能打包到代码的静态资源
static       # 所有图片、文件等不需要打包的静态资源
styles       # 公共样式
components   # 公共组件
router       # 路由
lang         # 国际化翻译
utils        # 公共工具类或函数
views        # 页面,对应路由
store        # 公共仓库
types        # TS类型声明
7.1.2 Vue 编码规范
  • 除了计算属性以外避免内联样式,动态切换可通过切换 Class 实现,比如枚举状态
  • 【强制】所有属性名称都使用小写字母加 - 方式,Vue 官方建议小写,因为 HTML 大小写不敏感,可能导致一些冲突问题隐患
  • 【强制】Vue 使用 props 时,需声明类型,且子组件禁止直接修改,如有需要可用 v-model 方式来简化调用方式
  • 【强制】双向绑定的字段需要初始化定义,否则后续需使用 $set 添加属性
  • 【强制】写操作一定要加 loading 防重复点击
  • 避免在 template 写过于复杂的计算逻辑,应该在 method 或者 computed 中使用
  • 【强制】禁止在 computed 属性中修改 data
  • 合理抽取组件、函数等提高代码复用性,建议代码行数 200-300 行,最大不得超过 500 行,超过 500 行的需注明原因
  • 尽量使用 v-if,如果遇频繁操作可使用 v-show
7.1.3 组件属性顺序
  1. name
  2. components / directives / filters
  3. extends / mixins
  4. model / props / propsData
  5. data / computed
  6. watch / 生命周期钩子
  7. methods
7.1.4 模板属性顺序
  1. is
  2. v-for / v-if / v-else-if / v-else / v-show / v-cloak
  3. v-pre / v-once
  4. id
  5. ref / key / slot
  6. 使用缩写 :,不建议 v-bind
  7. v-model
  8. 使用缩写 @,不建议 v-on
  9. v-html / v-text
7.1.5 其他注意事项
  • 组件当中有绑定原生事件或定时器,在组件注销前进行移除
  • 参考:Vue 风格指南

7.2 React

7.2.1 React 项目文件夹分类
复制代码
api          # 所有后台接口声明
assets       # 所有icon、图片、文件等可能打包到代码的静态资源
static       # 所有图片、文件等不需要打包静态资源
styles       # 公共样式
components   # 公共组件、公共容器
router       # 路由
lang         # 国际化
utils        # 公共工具类或函数
views        # 页面,对应路由
redux        # 公共仓库
types        # TS类型声明
7.2.2 React 编码规范
  • 尽量使用函数组件,推荐使用 React Hooks
  • 【强制】对于不影响 UI 更新的状态,使用 useRef 而非 useState
  • 【强制】所有 hooks 的定义必须在组件的第一层,禁止在 iffor、闭包中定义 hooks
  • 【强制】需要开启 ESLint 的 react-hooks 校验,若遇到 useEffect 空依赖报错,在确定只需要执行一次时,使用 // eslint-disable-line react-hooks/exhaustive-deps
  • 【强制】避免在 class 组件的 render 函数(或函数式组件)内部创建新的闭包
  • 不要使用数组的索引作为 key
  • 在专用组件中渲染列表
  • render 过于复杂时,应该拆分成若干组件
  • 遵循单一职责原则,使用 HOC / 装饰器 / Render Props 增加职责
  • 【强制】定义组件时,使用 interface 来代替 prop-types
  • state 往上层组件提取,让下层组件只需要实现为纯函数
  • 使用 setState 修改状态,但尽量合并操作,减少调用频次
  • 参考:React 性能优化

8. 图片规范

  • 【强制】图片需设置默认图片,添加 onerror 处理
  • 【强制】网站配置默认 favicon.ico 文件
  • 【强制】imgsrc 禁止为空,延迟加载也需要给默认图
  • 单张图片 PC 端小于 100KB,移动端小于 50KB
  • 质量标准为 65(肉眼辨别临界值),高质量为 80(用于下载)
  • 使用 SVG,图标去除颜色,由 CSS 控制颜色

9. 规范检测

ESLint / TSLint 详见配置文件

typescript 复制代码
{
 extends: [
   // 公共部分
   'plugin:import/errors', // https://www.npmjs.com/package/eslint-plugin-import
   'plugin:import/warnings',
   'plugin:@typescript-eslint/eslint-recommended', // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/eslint-recommended.ts
   'plugin:@typescript-eslint/recommended', // https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/configs/recommended.ts
   // react项目
   'plugin:react/recommended', // https://github.com/yannickcr/eslint-plugin-react#Recommended
   // vue项目
   'plugin:vue/essential', // https://eslint.vuejs.org/rules/no-arrow-functions-in-watch.html
   'plugin:vue/vue3-essential', // https://eslint.vuejs.org/rules/no-deprecated-data-object-declaration.html
  ],
  plugins: ['@typescript-eslint', 'import', 'react'],

// ES部分
  rules: {
   // 0-off, 1-warning, 2-error
   'max-len': [2, { 'code': 120, 'ignoreComments': true, 'ignoreTrailingComments': true, 'ignoreUrls': true}], // 每行长度最大120,忽略注释和url
   'accessor-pairs': 2, // 强制 getter 和 setter 在对象中成对出现
   'arrow-spacing': [2, { 'before': true, 'after': true }], // 强制箭头函数的箭头前后使用一致的空格
   'block-spacing': [2, 'always'], // 强制在代码块中开括号前和闭括号后有空格
   'brace-style': [2, '1tbs', { 'allowSingleLine': true }], // 强制在代码块中使用一致的大括号风格
   'camelcase': [0, { 'properties': 'always' }], // 不强制使用骆驼拼写法命名约定
   'comma-dangle': [2, 'always-multiline'], // 多行时要求末尾逗号
   'comma-spacing': [2, { 'before': false, 'after': true }], // 强制在逗号前后使用一致的空格
   'comma-style': [2, 'last'], // 强制使用一致的逗号风格
   'constructor-super': 2, // 要求在构造函数中有 super() 的调用
   'curly': 0, // 强制所有控制语句使用一致的括号风格
   'dot-location': [2, 'property'], // 强制在点号之前和之后一致的换行
   'eol-last': 2, // 要求文件末尾存在空行
   'eqeqeq': 2, // 要求使用 === 和 !==
   'generator-star-spacing': [2, { 'before': true, 'after': true }], // 强制 generator 函数中 * 号周围使用一致的空格
   'handle-callback-err': [2, '^(err|error)$'], // 要求回调函数中有容错处理
   'indent': [2, 2, { 'SwitchCase': 1 }], // 强制使用一致的缩进
   'jsx-quotes': [2, 'prefer-double'], // 强制在 JSX 属性中一致地使用双引号
   'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }], // 强制在对象字面量的属性中键和值之间使用一致的间距
   'keyword-spacing': [2, { 'before': true, 'after': true }], // 强制在关键字前后使用一致的空格
   'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }], // 要求构造函数首字母大写
   'new-parens': 2, // 强制调用无参构造函数时有圆括号
   'no-array-constructor': 2, // 禁用 Array 构造函数
   'no-caller': 2, // 禁用 arguments.caller 或 arguments.callee
   'no-console': 2, // 禁用 console
   'no-class-assign': 2, // 禁止修改类声明的变量
   'no-cond-assign': 2, // 禁止条件表达式中出现赋值操作符
   'no-const-assign': 2, // 禁止修改 const 声明的变量
   'no-control-regex': 2, // 禁止在正则表达式中使用控制字符
   'no-delete-var': 2, // 禁止删除变量
   'no-dupe-args': 2, // 禁止 function 定义中出现重名参数
   'no-dupe-class-members': 2, // 禁止类成员中出现重复的名称
   'no-dupe-keys': 2, // 禁止对象字面量中出现重复的 key
   'no-duplicate-case': 2, // 禁止出现重复的 case 标签
   'no-empty-character-class': 2, // 禁止在正则表达式中使用空字符集
   'no-empty-pattern': 2, // 禁止使用空解构模式
   'no-eval': 2, // 禁用 eval()
   'no-ex-assign': 2, // 禁止对 catch 子句的参数重新赋值
   'no-extend-native': 2, // 禁止扩展原生类型
   'no-extra-bind': 2, // 禁止不必要的 .bind() 调用
   'no-extra-boolean-cast': 2, // 禁止不必要的布尔转换
   'no-extra-parens': [2, 'functions'], // 禁止不必要的括号
   'no-fallthrough': 2, // 禁止 case 语句落空
   'no-floating-decimal': 2, // 禁止数字字面量中使用前导和末尾小数点
   'no-func-assign': 2, // 禁止对 function 声明重新赋值
   'no-implied-eval': 2, // 禁止使用类似 eval() 的方法
   'no-inner-declarations': [2, 'functions'], // 禁止在嵌套的块中出现变量声明或 function 声明
   'no-invalid-regexp': 2, // 禁止 RegExp 构造函数中存在无效的正则表达式字符串
   'no-irregular-whitespace': 2, // 禁止不规则的空白
   'no-iterator': 2, // 禁用 __iterator__ 属性
   'no-label-var': 2, // 不允许标签与变量同名
   'no-labels': [2, { 'allowLoop': false, 'allowSwitch': false }], // 禁用标签语句
   'no-lone-blocks': 2, // 禁用不必要的嵌套块
   'no-mixed-spaces-and-tabs': 2, // 禁止空格和 tab 的混合缩进
   'no-multi-spaces': 2, // 禁止使用多个空格
   'no-multi-str': 2, // 禁止使用多行字符串
   'no-multiple-empty-lines': [2, { 'max': 1 }], // 禁止出现多行空行
   'no-new-object': 2, // 禁用 Object 的构造函数
   'no-new-require': 2, // 禁止调用 require 时使用 new 操作符
   'no-new-symbol': 2, // 禁止 Symbolnew 操作符和 new 一起使用
   'no-new-wrappers': 2, // 禁止对 String,Number 和 Boolean 使用 new 操作符
   'no-obj-calls': 2, // 禁止把全局对象作为函数调用
   'no-octal': 2, // 禁用八进制字面量
   'no-octal-escape': 2, // 禁止在字符串中使用八进制转义序列
   'no-path-concat': 2, // 禁止对 __dirname 和 __filename 进行字符串连接
   'no-proto': 2, // 禁用 __proto__ 属性
   'no-redeclare': 2, // 禁止多次声明同一变量
   'no-regex-spaces': 2, // 禁止正则表达式字面量中出现多个空格
   'no-return-assign': [2, 'except-parens'], // 禁止在 return 语句中使用赋值语句
   'no-self-assign': 2, // 禁止自我赋值
   'no-self-compare': 2, // 禁止自身比较
   'no-sequences': 2, // 禁用逗号操作符
   'no-shadow-restricted-names': 2, // 禁止将标识符定义为受限的名字
   'no-sparse-arrays': 2, // 禁用稀疏数组
   'no-this-before-super': 2, // 禁止在构造函数中,在调用 super() 之前使用 this 或 super
   'no-throw-literal': 2, // 禁止抛出异常字面量
   'no-trailing-spaces': 2, // 禁用行尾空格
   'no-undef': 2, // 禁用未声明的变量,除非它们在 /*global */ 注释中被提到   'no-undef-init': 2, // 禁止将变量初始化为 undefined
   'no-unexpected-multiline': 2, // 禁止出现令人困惑的多行表达式
   'no-unmodified-loop-condition': 2, // 禁用一成不变的循环条件
   'no-unneeded-ternary': [2, { 'defaultAssignment': false }], // 禁止可以在有更简单的可替代的表达式时使用三元操作符
   'no-unreachable': 2, // 禁止在 return、throw、continue 和 break 语句之后出现不可达代码
   'no-unsafe-finally': 2, // 禁止在 finally 语句块中出现控制流语句
   'no-unused-vars': [2, { 'vars': 'all', 'args': 'none' }], // 禁止出现未使用过的变量
   'no-useless-call': 2, // 禁止不必要的 .call() 和 .apply()
   'no-useless-computed-key': 2, // 禁止在对象中使用不必要的计算属性
   'no-useless-constructor': 2, // 禁用不必要的构造函数
   'no-useless-escape': 0, // 禁用不必要的转义字符
   'no-whitespace-before-property': 2, // 禁止属性前有空白
   'no-with': 2, // 禁用 with 语句
   'one-var': [2, { 'initialized': 'never' }], // 强制函数中的变量要么一起声明要么分开声明
   'operator-linebreak': [2, 'after', { 'overrides': { '?': 'before', ':': 'before' }}], // 强制操作符使用一致的换行符
   'padded-blocks': [2, 'never'], // 禁止块内填充
   'quotes': [2, 'single', { 'avoidEscape': true, 'allowTemplateLiterals': true }], // 强制使用一致的反勾号、双引号或单引号
   'semi': [2, 'always'], // 要求使用分号代替 ASI
   'semi-spacing': [2, { 'before': false, 'after': true }], // 强制分号之前和之后使用一致的空格
   'space-before-blocks': [2, 'always'], // 强制在块之前使用一致的空格
   'space-before-function-paren': [2, 'never'], // 强制在 function的左括号之前使用一致的空格
   'space-in-parens': [2, 'never'], // 强制在圆括号内使用一致的空格
   'space-infix-ops': 2, // 要求操作符周围有空格
   'space-unary-ops': [2, { 'words': true, 'nonwords': false }], // 强制在一元操作符前后使用一致的空格
   'spaced-comment': [2, 'always', { 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] }], // 强制在注释中 // 或 /* 使用一致的空格
   'template-curly-spacing': [2, 'never'], // 禁止模板字符串中的嵌入表达式周围空格的使用
   'use-isnan': 2, // 要求使用 isNaN() 检查 NaN
   'valid-typeof': 2, // 强制 typeof 表达式与有效的字符串进行比较
   'wrap-iife': [2, 'any'], // 要求 IIFE 使用括号括起来
   'yield-star-spacing': [2, 'both'], // 强制在 yield* 表达式中 * 周围使用空格
   'yoda': [2, 'never'], // 禁止 "Yoda" 条件
   'prefer-const': 2, // 要求使用 const 声明那些声明后不再被修改的变量
   'no-debugger': 2, // 禁用 debugger
   'object-curly-spacing': [2, 'always', { 'objectsInObjects': true }], // 强制在大括号中使用一致的空格
   'array-bracket-spacing': [2, 'never'], // 强制数组方括号中使用一致的空格'
   // eslint-plugin-import 相关
   'import/no-unresolved': 2, // 禁止从无法匹配的路径中import依赖(路径区分大小写)
   'import/default': 2, // 禁止从没有默认导出的模块中请求默认导入
   'import/no-absolute-path': 2, // 禁止从绝对路径中导入
   'import/no-self-import': 2, // 禁止模块导入自己
   'import/no-duplicates': 2, // 禁止多次从同一个模块中导入
   'import/order': [2, {'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object']}], // 规范导入顺序, https://github.com/benmosher/eslint-plugin-import/blob/HEAD/docs/rules/order.md#importorder-enforce-a-convention-in-module-import-order
   'import/export': 2, // 禁止无效导出
}

// React部分
rules: {
   // eslint-plugin-react 相关
   'react/jsx-boolean-value': 'never', // 布尔值的prop值为true时使用简写
   'react/jsx-closing-bracket-location': 2, // 正确关闭组件标签
   'react/display-name': 0, // 必须设置display name
   'react/jsx-equals-spacing': 2, // 强制等号周围存在空格
   'react/jsx-filename-extension': [2, {'extensions': ['.jsx', '.tsx']}], // react组件的文件名后缀强制为jsx或tsx
   'react/jsx-handler-names': 'off', // 统一事件handler的命名,可讨论
   'react/jsx-indent-props': [2, 2], // prop前缩进为2
   'react/jsx-indent': [2, 2], // 缩进为2
   'react/jsx-key': 2, // 循环渲染的组件必须有key
   'react/jsx-no-bind': [2, {'ignoreRefs': true}], // 禁止prop使用Function.prototype.bind和箭头函数,但忽略ref
   'react/jsx-no-duplicate-props': 2, // 禁止重复prop
   'react/jsx-no-literals': 0, // 禁止在JSX中使用字符串文字
   'react/jsx-no-target-blank': 2, // 禁止target="_blank"的a标签不设置rel="noreferrer"
   'react/jsx-no-undef': 2, // 禁止使用未定义的变量
   'react/jsx-pascal-case': 2, // 组件名必须使用pascal case
   'react/jsx-sort-props': 0, // prop按字典序排序
   'react/jsx-tag-spacing': 2, // 校验JSX开闭标签周围的空格
   'react/jsx-uses-react': 0, // 防止React被错误地标记为未使用
   'react/jsx-uses-vars': 2, // 防止将JSX中使用的变量错误地标记为未使用
   'react/no-array-index-key': 2, // 禁止使用数组的index作为组件的key
   'react/no-children-prop': 2, // 禁止将prop命名为children
   'react/no-danger': 1, // 防止使用危险的jsx属性
   'react/no-deprecated': 2, // 禁止使用deprecated的方法
   'react/no-did-mount-set-state': 0, // 禁止在didMount时setState
   'react/no-did-update-set-state': 2, // 禁止在didUpdate时setState
   'react/no-will-update-set-state': 2, // 禁止在willUpdate时setState
   'react/no-direct-mutation-state': 2, // 禁止对this.state直接赋值
   'react/no-find-dom-node': 2, // 禁止使用findDOMNode
   'react/no-is-mounted': 2, // 禁止使用isMounted
   'react/no-multi-comp': [2, {'ignoreStateless': true}], // 禁止在一个文件中定义多个class组件
   'react/no-set-state': 0, // 禁止使用setState
   'react/no-unknown-property': 2, // 禁止使用未知的DOM属性
   'react/no-unused-prop-types': 2, // 禁止定义未使用的propTypes
   'react/prefer-stateless-function': 2, // 强制 stateless Components 写成 pure function
   'react/prop-types': 0, // 禁止缺少propType定义(使用ts就不需要)
   'react/require-default-props': 2, // 非required prop必须有defaultProps
   'react/require-render-return': 2, // render方法必须有返回值
   'react/self-closing-comp': [2, {'html': false}], // 防止没有子组件的组件使用额外的结束标签
   'react/sort-prop-types': 0, // propTypes按字典序排序
   'react/style-prop-object': 2, // style属性必须是object
   'react/sort-comp': [ // 强制class组件内的属性、生命周期等的定义顺序
     2,
     {
         'order': [
             'static-properties',
             'static-methods',
             'state',
             'properties',
             'lifecycle',
             'everything-else',
             'render'
         ],
         'groups': {
             'static-properties': [
                 'displayName',
                 'propTypes',
                 'contextTypes',
                 'childContextTypes',
                 'mixins',
                 'statics'
             ],
             'lifecycle': [
                 'getDefaultProps',
                 'getInitialState',
                 'constructor',
                 'getChildContext',
                 'componentWillMount',
                 'componentDidMount',
                 'componentWillReceiveProps',
                 'shouldComponentUpdate',
                 'componentWillUpdate',
                 'componentDidUpdate',
                 'componentWillUnmount'
             ]
         }
     }
  ]
}

// Vue部分
rules: {
   "vue/component-definition-name-casing": [2, "PascalCase"], // 强制组件的name使用PascalCase
   "vue/html-closing-bracket-newline": [2, {"singleline": "never", "multiline": "always"}], // 统一组件关闭标签换行风格
   "vue/html-closing-bracket-spacing": [2, {"startTag": "never", "endTag": "never", "selfClosingTag": "always"}], // 统一组件关闭标签空格风格
   "vue/html-end-tags": 2, // 原生html标签必须有闭标签
   "vue/html-indent": [2, 2, {"attribute": 1, "baseIndent": 1, "closeBracket": 0}], // html标签缩进为2
   "vue/html-quotes": [2, "double"], // html属性使用双引号
   "vue/html-self-closing": [2, {
       "html": {
       "void": "never",
       "normal": "always",
       "component": "always"
       },
       "svg": "always",
       "math": "always"
   }], // 没有子组件的组件标签自关闭
   "vue/max-attributes-per-line": 0, // 不限制组件每行的属性数
   "vue/mustache-interpolation-spacing": [2, "never"], // 模板中渲染变量的括号中不需要空格
   "vue/no-multi-spaces": [2, {"ignoreProperties": false}], // 不允许出现多个无用的空格
   "vue/no-spaces-around-equal-signs-in-attribute": [2], // 组件属性中的等号旁不允许有空格
   "vue/no-template-shadow": 2, // 禁止在外部范围中声明的阴影变量中声明变量
   "vue/prop-name-casing": [2, "camelCase"] // 组件prop命名使用camelCase
   "vue/require-default-prop": 2, // 非require的prop需要有默认值
   "vue/require-prop-types": 2, // 组件props必须有类型定义
   "vue/v-bind-style": [2, "shorthand"], // v-bind指令必须使用缩写
   "vue/v-on-style": [2, "shorthand"], // v-on指令必须使用缩写
   "vue/component-tags-order": [2, {"order": ["template", "script", "style"]}], // 文件内标签定义顺序 template > script > style
   "vue/order-in-components": [2, {"order": [ // 组件内容的定义顺序
       "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",
       "setup",
       "asyncData",
       "data",
       "fetch",
       "head",
       "computed",
       "watch",
       "watchQuery",
       "LIFECYCLE_HOOKS",
       "methods",
       ["template", "render"],
       "renderError"
   ]}],
   "vue/this-in-template": [2, "never"] // 模板中无需写this
}

📝 总结

本规范涵盖了前端开发的各个方面,包括:

  • 公共规范:文件命名、代码格式、编码规范
  • HTML 规范:语义化标签、嵌套规范
  • CSS 规范:命名、属性顺序、性能优化
  • JS 规范:命名、函数、变量、异常处理
  • 框架规范:Vue 和 React 的详细使用规范
  • 图片规范:图片处理和优化要求

遵循本规范可以确保代码的一致性、可维护性和高质量。

相关推荐
心柠2 小时前
webpack
前端·webpack·node.js
Zhu_S W2 小时前
基于Java和Redis实现排行榜功能
前端·bootstrap·html
小马_xiaoen2 小时前
Vue3 + TS 实现长按指令 v-longPress:优雅解决移动端/PC端长按交互需求
前端·javascript·vue.js·typescript
147API2 小时前
改名后的24小时:npm 包抢注如何劫持开源项目供应链
前端·npm·node.js
ziqi5222 小时前
第二十二天笔记
前端·chrome·笔记
鹤归时起雾.2 小时前
react一阶段学习
前端·学习·react.js
2301_780669862 小时前
HTML-CSS-常见标签和样式(标题的排版、标题的样式、选择器、正文的排版、正文的样式、整体布局、盒子模型)
前端·css·html·javaweb
mseaspring3 小时前
一款高颜值SSH终端工具!基于Electron+Vue3开发,开源免费还好用
运维·前端·javascript·electron·ssh
appearappear3 小时前
wkhtmltopdf把 html 原生转成成 pdf
前端·pdf·html