AlexZ33 / lessions

自己练习的各种demo和课程
12 stars 2 forks source link

前端开发的规范 #4

Open AlexZ33 opened 5 years ago

AlexZ33 commented 5 years ago

前端团队代码评审 CheckList 清单

制定自己团队的前端开发规范

js编码规范 - 强制

AlexZ33 commented 5 years ago

css编码规范 - 强制

AlexZ33 commented 5 years ago

代码管理

使用Git 静态资源使用OSS https://code.aliyun.com/

代码实践

这一部分的内容很难具体衡量。代码风格是否遵守是可以量化,并通过工具检查的;然而逻辑却很难评价。这个变量名是好的吗?这样的逻辑是低耦合的吗?凡此种种,所以只能说是代码风格的“建议”

拒绝流水账

把所有逻辑像摊大饼一样铺开来可能是最简单省力的写法,但是这样的代码是不可维护的。始终要有一个意识:需求总是在变动,不可维护的代码会成为每个人的梦魇。

可能在刚开始的时候,你会写出一块纯粹的线性逻辑,但是之后就要想:有那些部分是可以提取的?你的模块是否定义的合适?一个很显而易见的指标是一个函数应该只做一件事情。

不要写出这种模块:

let o = {
    count: 0
}

(function () {
    o.count++
})()

而是提供接口给使用者:

et o = {
    count: 0,
    add() {
        this.count++
    }
}

(function() {
    o.add()
})()

边界值

是不是常用这种情况?

axios('url', function(res) {
    return(res.data.value.itemArr.length)
})

这种写法是错误的!意味着你默认 res.data 有 value 这个属性,value 有 itemArr 这个数组属性——然而这个值是从接口返回的。假设接口返回一个null,你的js会因此报错,然后停止运行。最坏的情况,页面会直接挂掉。

不要信任第三方的变量。不要假定他们一定有某种数据结构。你要写出健壮的代码。

即使是你自己提供的值,也要加倍小心,只要变量的类型不确定,就应该做判断。

通用规范

编码统一使用UTF8 文件名和URL中避免使用中文 只能使用空格缩进,禁止使用Tab Google Style Guides

HTML/CSS

Google HTML/CSS Style Guide Bootstrap编码规范

Bad

.avatar{
    border-radius:50%;
    border:2px solid white; }
.no, .nope, .not_good {
    // ...
}
#lol-no {
  // ...
}

Good

.avatar {
  border-radius: 50%;
  border: 2px solid white;
}

.one,
.selector,
.per-line {
  // ...
}

css注释

参考资料:

Nicole Sullivan 的 OOCSS wiki Smashing Magazine 的 Introduction to OOCSS BEM,也就是 “Block-Element-Modifier”,是一种用于 HTML 和 CSS 类名的命名约定。BEM 最初是由 Yandex 提出的,要知道他们拥有巨大的代码库和可伸缩性,BEM 就是为此而生的,并且可以作为一套遵循 OOCSS 的参考指导规范。

示例

<article class="listing-card listing-card--featured">

  <h1 class="listing-card__title">Adorable 2BR in the sunny Mission</h1>

  <div class="listing-card__content">
    <p>Vestibulum id ligula porta felis euismod semper.</p>
  </div>

</article>
.listing-card { }
.listing-card--featured { }
.listing-card__title { }
.listing-card__content { }

.listing-card是一个块(block),表示高层次的组件。 .listing-card__title 是一个元素(element),它属于 .listing-card的一部分,因此块是由元素组成的。 .listing-card--featured 是一个修饰符(modifier),表示这个块与.listing-card有着不同的状态或者变化。

ID 选择器

在 CSS 中,虽然可以通过 ID 选择元素,但大家通常都会把这种方式列为反面教材。ID 选择器给你的规则声明带来了不必要的高优先级,而且 ID 选择器是不可重用的。

想要了解关于这个主题的更多内容,参见 CSS Wizardry 的文章,文章中有关于如何处理优先级的内容。

JavaScript 钩子

避免在 CSS 和 JavaScript 中绑定相同的类。否则开发者在重构时通常会出现以下情况:轻则浪费时间在对照查找每个要改变的类,重则因为害怕破坏功能而不敢作出更改。

我们推荐在创建用于特定 JavaScript 的类名时,添加 .js- 前缀:

<button class="btn btn-primary js-request-to-book">Request to Book</button>

边框

在定义无边框样式时,使用 0 代替 none。

Bad

.foo {
  border: none;
}

Good

.foo {
  border: 0;
}

JavaScript

Google JavaScript Style Guide Airbnb JavaScript编码规范 Airbnb React/JSX编码规范 Vue.js风格指南 Vue.js组件编码规范 Node.js编码规范

Python

Google Python Style Guide

Java

Google Java Style Guide 阿里巴巴Java开发手册

Git协作规范

Gitflow 工作流

Gitflow工作流通过为功能开发、发布准备和维护分配独立的分支,让发布迭代过程更流畅。严格的分支模型也为大型项目提供了一些非常必要的结构。

Git Workflows: Gitflow Cycle

Gitflow工作流定义了一个围绕项目发布的严格分支模型。提供了用于一个健壮的用于管理大型项目的框架。为不同的分支分配一个明确的角色,并定义分支之间如何和什么时候进行交互。 除了使用功能分支,在做准备、维护和记录发布时,也定义了各自的分支。并包含功能分支工作流的Pull Requests、隔离实验性开发和更高效的协作。

1 工作方式

Gitflow工作流仍然用中央仓库作为所有开发者的交互中心。开发者在本地工作并push分支到要中央仓库中。

2 历史分支

Gitflow工作流主要使用两个分支来记录项目的历史。 master分支存储了正式发布的历史,而develop分支作为功能的集成分支。

3 功能分支

每个新功能位于一个自己的分支,这样可以push到中央仓库以备份和协作。 但功能分支不是从master分支上拉出新分支,而是使用develop分支作为父分支。当新功能完成时,合并回develop分支。 新功能提交应该从不直接与master分支交互。

4 发布分支

一旦develop分支上有了做一次发布(或者说快到了既定的发布日)的足够功能,就从develop分支上checkout一个发布分支。 新建的分支用于开始发布循环,所以从这个时间点开始之后新的功能不能再加到这个分支上—— 这个分支只应该做Bug修复、文档生成和其它面向发布任务。 一旦对外发布的工作都完成了,发布分支合并到master分支并分配一个版本号打好Tag。 另外,这些从新建发布分支以来的做的修改要合并回develop分支。

使用一个用于发布准备的专门分支,使得一个团队可以在完善当前的发布版本的同时,另一个团队可以继续开发下个版本的功能。

常用的分支约定:

用于新建发布分支的分支: develop
用于合并的分支: master
分支命名: release-* 或 release/*

5 维护分支

维护分支或说是热修复(hotfix)分支用于给产品发布版本(production releases)快速生成补丁,这是唯一可以直接从master分支fork出来的分支。 修复完成,修改应该马上合并回master分支和develop分支(当前的发布分支),master分支应该用新的版本号打好Tag

Bug修复使用专门分支,让团队可以处理掉问题而不用打断其它工作或是等待下一个发布循环。可以把维护分支想成是一个直接在master分支上处理的临时发布。

6 示例

下面的示例演示本工作流如何用于管理单个发布循环。假设你已经创建了一个中央仓库。

创建开发分支

第一步为master分支配套一个develop分支。简单来做可以本地创建一个空的develop分支,push到服务器上:

# 该步骤已完成
git branch dev_20190311
git push -u origin dev_20190311

以后这个分支将会包含了项目的全部历史,而master分支将只包含了部分历史。其它开发者这时应该克隆中央仓库,建好develop分支的跟踪分支:

git clone ssh://user@host/path/to/repo.git
git checkout -b develop origin/dev_20190311

现在每个开发都有了这些历史分支的本地拷贝。

A 和 B 开始开发新功能

开始各自的功能开发。他们需要为各自的功能创建相应的分支。新分支不是基于master分支,而是应该基于develop分支:

git checkout -b feature-some develop

推送特色分支到中央仓库:

git push -u origin feature-some
# 远程仓库名称如果需要修改
git push -u origin feature-some:feature-other

用老套路添加提交到各自功能分支上:编辑、暂存、提交:

git status
git add <some-file>
git commit

A 完成功能开发

添加了提交后,A 觉得他的功能 OK 了。如果团队使用Pull Requests,这时候可以发起一个用于合并到develop分支。 否则他可以直接合并到他本地的develop分支后push到中央仓库:

# 该步骤采用线上发起`Pull Requests`,一下操作省略
# 操作地址:http://phoebus.cnsuning.com/#/repositoryManageBySystem
git pull origin develop
git checkout develop
git merge some-feature
git push
git branch -d some-feature

第一条命令在合并功能前确保develop分支是最新的。注意,功能决不应该直接合并到master分支。 冲突问题全部在本地解决。

A 开始准备发布

这个时候 B 正在实现他的功能,A 开始准备他的第一个项目正式发布。 像功能开发一样,他用一个新的分支来做发布准备。这一步也确定了发布的版本号:

git checkout -b release-0.1 develop

这个分支是清理发布、执行所有测试、更新文档和其它为下个发布做准备操作的地方,像是一个专门用于改善发布的功能分支。

只要 A 创建这个分支并push到中央仓库,这个发布就是功能冻结的。任何不在develop分支中的新功能都推到下个发布循环中。

A 完成发布

一旦准备好了对外发布,A 合并修改到master分支和develop分支上,删除发布分支。合并回develop分支很重要,因为在发布分支中已经提交的更新需要在后面的新功能中也要是可用的。

这是一个发起Pull Request的理想时机,并进行Code Review

git checkout master
git merge release-0.1
git push
git checkout develop
git merge release-0.1
git push
git branch -d release-0.1

发布分支是作为功能开发(develop分支)和对外发布(master分支)间的缓冲。只要有合并到master分支,就应该打好Tag以方便跟踪。

git tag -a 0.1 -m "Initial public release" master
git push --tags

最终用户发现Bug

对外版本发布后,A、B 一起开发下一版本的新功能,直到有最终用户开了一个Ticket抱怨当前版本的一个Bug。 为了处理Bug,A(或 B)从master分支上拉出了一个维护分支,提交修改以解决问题,然后直接合并回master分支:

git checkout -b issue-#001 master
# Fix the bug
git checkout master
git merge issue-#001
git push

就像发布分支,维护分支中新加这些重要修改需要包含到develop分支中,所以 A 要执行一个合并操作。然后就可以安全地删除这个分支了:

git checkout develop
git merge issue-#001
git push
git branch -d issue-#001

常见文档

http://uprogrammer.cn/

流程规范

评审阶段