编程规范
记录自己所总结和遵守的编程规范(即个人风格指南)
命名规范与项目结构
命名规范
命名规范是编程规范中最重要的一部分,它直接影响到代码的可读性和可维护性
常用的命名形式
camelCase
小驼峰式命名法(首字母小写)PascalCase
大驼峰式命名法(首字母大写)snake_case
下划线命名法kebab-case
短横线命名法UPPER_CASE
大写命名法
文件命名规范
INFO
除组件命名外,均使用短横线命名法
- 项目名称使用短横线命名法。🌰
mm-notes
- 文件夹名称使用短横线命名法。🌰
src / utils / hooks
html / css / md / js / ts / jsx / tsx
文件使用短横线命名法React / Vue
组件文件使用大写驼峰式命名法。🌰Dialog.vue
/Dialog.tsx
- 静态资源文件使用短横线命名法。🌰
logo-white.png
代码命名规范
JavaScript 命名规范
- 常量使用大写命名法。🌰
const MAX_COUNT = 1996
- 正则常量命名使用后缀
_RE
。🌰const PHONE_RE = /^1[3-9]\d{9}$/
- 正则常量命名使用后缀
- 变量使用小驼峰式命名法。🌰
const maxCount = 1996
class
类名使用大驼峰式命名法。🌰class User {}
- 构造函数使用大驼峰式命名法。🌰
function User() {}
- 函数使用小驼峰式命名法。🌰
function getUserInfo() {}
- 对象
key
使用小驼峰式命名法。🌰const user = { userName: 'maomao' }
- 路由
path
使用短横线命名法。🌰path: '/user-info'
常用命名前缀 | 含义 | 🌰 |
---|---|---|
can | 判断是否可执行某个动作 | canDelete() 是否可删除 |
has | 判断是否含有某个值 | hasPermission() 是否有权限 |
is | 判断是否为某个值 | isActive 是否处于活动状态 |
get | 获取某个值 | getUserName() 获取用户名 |
set | 设置某个值 | setUserName() 设置用户名 |
reset | 重置某个值 | resetUserName() 重置用户名 |
clear | 清除某个值 | clearUserName() 清除用户名 |
format | 格式化某个值 | formatDate() 格式化日期 |
validate | 验证某些值或条件 | validateUserName() 验证用户名 |
create | 创建操作 | createUser() 创建用户对象 |
delete | 删除操作 | deleteUser() 删除用户 |
update | 更新操作 | updateUser() 更新用户 |
render | 渲染视图或 UI 元素 | renderTable() 渲染表格 |
on | 用于组件对外暴露事件 | onSubmit() 提交表单 |
handle | 用于事件处理函数的命名 | handleClick() 点击事件 |
use | React / Vue 自定义 hook | useFetch() 自定义请求 hook |
HTML 标签属性命名规范
html
标签属性使用短横线命名法。🌰<div class="user-info" data-index="0"></div>
CSS 命名规范
- 类名使用短横线命名法。🌰
.user-info
ID
使用小驼峰式命名法。🌰#userInfo
- 自定义变量使用短横线命名法。🌰
--main-color: #fff
项目结构
约定优于配置
sh
.
├── .vscode # VSCode 配置文件
├── public # 网站资源文件(favicon.ico index.html 等)
├── scripts # 脚本相关
├── src
│ ├── apis # api 接口
│ ├── assets # 静态资源
│ ├── components # 全局组件
│ ├── config # 项目配置文件
│ ├── constants # 常量
│ ├── hooks # 通用 hooks
│ ├── layout # 页面整体布局
│ ├── lib # 第三方或无业务依赖代码
│ ├── locales # i18n
│ ├── pages # 页面相关文件
│ │ ├── Home # 大驼峰规范 => 组件即是一个构造函数
│ │ │ ├── components # 页面相关的子组件
│ │ │ ├── index.module.scss # 根据应用的 CSS Scope 方案命名
│ │ │ └── index.tsx # index 作为默认路径,视为根节点
│ │ └── App.tsx # 页面入口
│ ├── router # 页面路由
│ ├── store # 状态管理
│ ├── styles # 全局/基础样式
│ ├── types # TypeScript 类型声明
│ ├── utils # 工具函数
│ └── main.tsx # 应用启动入口
├── README.md # 当前项目的文档
├── package.json # 项目信息
└── tsconfig.json # TypeScript 配置文件
Git
规范
分支管理和命名规范
使用 Git Flow 工作流进行分支管理
master
主分支- 用于存放对外发布的稳定版本(不能直接在该分支上开发,只能从
develop
分支合并过来)
- 用于存放对外发布的稳定版本(不能直接在该分支上开发,只能从
develop
开发分支- 用于存放最新的开发版本(所有新功能都以该分支来创建自己的开发分支,该分支只做合并操作,不能直接在该分支上开发)
feature
功能分支- 用于开发新功能(在
develop
上创建分支,以自己开发功能模块命名,功能测试正常后合并到develop
分支) feature
分支推荐命名规范:feature/日期-开发者-功能模块
- 用于开发新功能(在
hotfix
紧急 bug 修复分支- 用于修复线上版本的 bug(在
master
分支上创建,修复完成后合并到master
) hotfix
分支推荐命名规范:hotfix/日期-开发者-修复内容
- 用于修复线上版本的 bug(在
release
预发布分支- 用于当需要为发布新版做准备时(在
develop
上创建分支,以版本号命名,测试完成后合并到master
和develop
) release
分支推荐命名规范:release/版本号
- 用于当需要为发布新版做准备时(在
在日常开发时可以使用 Sourcetree 的 git-flow
来进行管理(点击『仓库 > git-flow
』)
commit
提交规范
git commit message
的格式
sh
<type>(<scope>): <subject>
<body>
<footer>
type
(必填):commit
的类型scope
(选填):commit
的影响范围subject
(必填):commit
信息的简短描述(50 字以内)body
(选填):commit
信息的具体描述footer
(选填):重大变化(Breaking Change
)和需要关闭的Issue
正则校验规则:
js
/**
* 基于 vue 项目中的 verify-commit-msg.js 修改
* https://github.com/vuejs/vue/blob/main/scripts/verify-commit-msg.js
*/
const commitRE =
/^((revert|wip|draft): )?(feat|fix|docs|style|refactor|perf|types|test|build|ci|chore)(\(.+\))?: .{1,50}/
commit
常用的 type
type | 含义 |
---|---|
feat | 新功能 |
fix | 修复 bug |
docs | 文档类改动 |
style | 代码格式改动,同理适用于业务样式调整 |
refactor | 重构(即不是新增功能,也不是修复 bug) |
perf | 性能优化相关 |
types | TypeScript 类型相关的改动 |
test | 单元测试、e2e 测试 |
build | 构建工具或者依赖项的改动 |
ci | 修改项目持续集成流程 |
chore | 其他类型的提交 |
revert | 恢复或还原相关提交 |
wip | draft | 托管平台对应的草稿标识 |
Prettier
使用 Prettier 对代码进行格式化,从而实现一致的编码风格
js
/**
* Prettier 配置项
* https://prettier.io/docs/en/options.html
*/
module.exports = {
// 每行代码的最佳长度,超出该长度则格式化
printWidth: 100,
// 一个缩进使用 2 个空格
tabWidth: 2,
// 缩进使用空格
useTabs: false,
// 语句末尾不添加分号
semi: false,
// 仅在必需时为对象的 key 添加引号
quoteProps: 'as-needed',
// 使用单引号
singleQuote: true,
// 在 jsx 中使用双引号
jsxSingleQuote: false,
// 添加尾随逗号
trailingComma: 'all',
// 在对象花括号内的两旁添加空格 => { foo: bar }
bracketSpacing: true,
// HTML元素(包括 JSX 等)具有多个属性时,将结束标签右尖括号 > 另起一行
bracketSameLine: false,
// 箭头函数仅有一个参数时,参数也添加括号 (x) => x
arrowParens: 'always',
// 每个文件格式化的范围是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 对所有文件进行格式化,而不是只对在开头含有特定注释(@prettier 或 @format)的文件进行格式化
requirePragma: false,
// 格式化的同时自动插入 @format 的特殊注释(表示该文件已被格式化)
insertPragma: false,
// 对 Markdown 文本换行不进行任何操作,保持原样
proseWrap: 'preserve',
// 对 HTML 全局空白不敏感
htmlWhitespaceSensitivity: 'ignore',
// 不对 vue 中的 script 及 style 标签进行缩进
vueIndentScriptAndStyle: false,
// 换行符使用 lf
endOfLine: 'lf',
// 自动格式化嵌入的代码内容
embeddedLanguageFormatting: 'auto',
// 不强制 html vue jsx 中的属性(具有多个时)单独占一行
singleAttributePerLine: false
}
TIP
为了方便使用,已发布到 npm
sh
# 安装
pnpm add -D @femm/prettier
# 引入配置
npm pkg set prettier='@femm/prettier'
# OR
echo "module.exports = require('@femm/prettier')" > .prettierrc.cjs