业界 作者:SegmentFault 2021-10-10 23:46:29 阅读:1193


复用:功能、组件是否可以提取公共方法?是否重复造轮子?同一代码不应该重复两次以上。
可扩展:当需求发生改动,是否能够使用少量的改动达到我们的目标,适应未来的变化?
过度设计:很多时候由于早期为了能够拥有更好的扩展性,进行了很多抽象和封装,使其复杂化,造成了过度设计。
依赖倒置:模块之间的依赖是否合理?一旦模块发生修改,影响面是否能得到有效的控制?
命名:首先格式(中划线、小驼峰、大驼峰、下划线)需要符合规范,不管是文件命名或者变量命名,尽可能符合其功能特性,能够通过命名知道它的含义,无须增加注释去特意说明。
注释:是否在关键代码内增加注释说明?是否符合正确的规范?
复杂度:复杂度是否在合理范围阈值,推荐文章前端代码质量-圈复杂度原理和实践(https://juejin.cn/post/6844903965792927751)
不合理的代码:每个项目都有一些难以维护的旧代码,在这个基础上继续添加代码,也许可以很快的解决当下问题,但对于日后来说,只会让它更加难以维护。及时对不合理的旧代码进行重构和优化就显得尤为重要。
XSS:XSS攻击详细内容,推荐文章前端安全系列(一):如何防止XSS攻击?https://tech.meituan.com/2018/09/27/fe-security.html
CSRF:CSRF攻击详细内容,推荐文章前端安全系列(二):如何防止CSRF攻击?https://tech.meituan.com/2018/10/11/fe-security-csrf.html
逻辑边界处理:是否有考虑到代码的边界逻辑?交互逻辑是否全面?
异常错误处理:一旦抛出异常或者错误,页面或者运行的代码是否会崩溃?
资源释放:定时器是否及时清空?内存及时清理?
兼容性:是否有浏览器版本兼容?手机机型兼容?历史数据兼容?接口兼容?小程序版本兼容?
数据展示:对于资产、购物车金额等关键数据的展示,尽可能直接展示后台返回数据,前端不做计算。
数据校验:对传输/接收的数据都进行校验、认证,确保数据的来源和正确。校验有效位、计算精度、完整性、一致性、时效性(获取时机是否正确、缓存是否更新)
数据转换:数据转换处理一定要经过充分的测试验证,并且尽量选取源数据进行传输,而并非转换后的数据。
夹带私货,比如,上个迭代有一个影响不大的小Bug,趁着还没被发现,偷偷将它带上线,或者,发现上一次写的代码太蠢了,还有更好的解决思路,于是洁癖发作,默默地改了,还觉得自己棒呆了。但是测试只知道本次迭代的功能特性,除了回归主功能之外,并不知道还有其他需要重新测试的地方。如果开发同学刚好对自己的代码非常自信,觉得一定没问题,没有通知到测试回归。根据墨菲定律,这种往往觉得没有问题的代码,最后...都能够引发线上故障。影响范围:底层架构、组件或者方法的修改,是否确认影响范围,每个受影响的依赖都能正常使用。
修改范围:是否属于本次迭代正常上线的功能范围,有没有对本次范围进行变更,是否通知到测试同学。
监控:监控一般用于监控数据的异常的情况,页面的渲染异常、数据的一致性、正确性。比如:在一些关键数据的逻辑上,如果接口返回的数据与原有约定不一致,添加了监控之后,我们就能快速的响应、解决问题。不至于等到引发更多的错误之后,才能看到问题。
埋点:埋点一般用于统计用户操作行为的数据,大部分场景下需要埋点的数据产品经理都会提供。
敏感信息展示:用户关键敏感信息是否直接展示。
敏感信息明文上报:用户关键敏感信息是否直接明文传给后台,没有做加密处理等操作。
敏感信息存储:保证用户信息的安全,对用户的敏感信息不存储在不安全的地方,比如web storage等。
图片大小:图片是否有进行过压缩处理,非页面级的图片一般不要超过200kb。http请求:页面初始化请求过多?白屏时间过长?初始化加载数据是否在合理范围内?懒加载:是否可以通过懒加载或者按需加载进行优化?缓存数据:需要重复加载数据时,可以通过缓存数据减少请求。checklist:在review的过程中,可以发现很多TODO List,比如增加了配置,在上线前需要先发布配置平台,比如增加片,要记得发布CDN,比如测试环境添加了测试代码,需要生产重新测试等等,所以在每次CR时,可以生成一份上线前的checklist,每次上线前查看并执行,这样能够确保不会遗漏。
少吃多餐:经过很多次的CR能够感觉到,每次评审的代码越多,质量就会降低,评审时间过长,都会产生疲劳感,并且一些小细节都会更容易忽略。所以每次评审的时间最好控制在30min~60min左右为佳,可发起多次评审,少吃多餐~
好的代码:每次CR都在像是找茬,找到不合理的地方。但其实,找到优秀合理的代码也可以促进大家的进步。大多数项目CR并不是全员参加,所以将好的代码整理出来,生成一份最佳实践,可以供大家学习参考,扩展一些新思路。
// package.json
// before
{
"dependencies": {
"eslint": "7.27.0",
"eslint-plugin-vue": "7.15.1",
},
}
// after
{
"dependencies": {
"eslint-plugin-vue": "^7.15.1",
"typescript": "^4.3.2"
},
}
数量,但是在a文件命名quantity,b文件命名amount,c文件命名count。// a.js
const quantity = 1;
// b.js
const amount = 1;
// c.js
const count = 1;
undefined。尽量避免文件之间的相互依赖,可以使用eslint或者webpack进行约束。// a.js
import b from b.js'
// b.js
import a from 'a.js'
if (!somethingA || somethingB && (!somethingC || somethingD)) {
...
}
or
if (...) {
if (...) {
...
} else if (...) {
...
} else {
...
}
} else {
...
}
// before
if (type === 1) {} else {}
// after
if (type === 1 && isShow) {} else {}
// else为空,确认无需处理
if (conditionA) {}
// 报错catch
UserService.getList().then()
// try...catch,未处理catch
try {...} catch() {}
setTimeout的取值方式相信很多人都见过,使用500毫秒的延迟,使偶现的问题,“不再出现”。但其实只是将出现的概率变小了,该出现的问题还是会出现。治标不治本。一定要找到出现问题的原因,真正解决它。setTimeout(() => {
...延时拉取接口 or do something
}, 500)
=> 正确 !== 小概率出错
xxx is undefined,大部分的原因主要是因为我们在对象取值时,喜欢直接点点点。建议使用lodash的get或者?.??。const a = productObj.something.a;
=> productObj.something是否一定有值?
// lodash
const a = get(productObj, 'something.a')
// 或者双问号操作符
?.??
==可以使用eslint避免。if ( amount == '22' ) {}
+new Date()
.page {
font-size: 18px;
font-family: sans-serif;
line-height: 18px;
color: #000;
...
.box {
font-size: 18px;
font-family: sans-serif;
line-height: 18px;
color: #000;
...
}
}

