一、为啥要 cr
1、通过团队内相互审核,交叉排查缺陷,以避免代码层面出现明显的问题。
2、通过团队成员的互相监督,在实现功能的基础上不断改善代码结构,以提高代码质量。
3、建立团队意识,意识到代码是团队的共同财产,在相互督促和改进中共同成长。
二 、如何 cr
三 、常见问题
1.没有README文档、或者README太简单、太作用有限
除了项目的READMD,每个模块都应该有各自的README,说明这个模块的功能点、技术实现方案等,看个人习惯。
2.console.log
(1)使用构建工具(如Webpack)的插件或配置:可以使用 Webpack 的 UglifyJs 插件或其他相关插件,在构建时自动移除或注释掉 console.log 语句。例如,在 Webpack 的配置文件中添加如下插件配置:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
// ...其他配置
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console: true, // 移除 console.log
},
},
}),
],
},
}
(2)使用 eslint 插件或规则:可以使用 eslint 的插件或规则,在开发过程中通过静态代码检查移除或注释掉 console.log。例如,安装并配置 eslint-plugin-no-console 插件,在 .eslintrc
或 .eslintrc.js
文件中添加如下配置:
module.exports = {
plugins: ['no-console'],
rules: {
'no-console': 'error',
},
};
3. 严格的等于
不严格的等于,前端需要找一个id = 5,而后端返回了一个id = '5'
let num = 0
let str = "0"
let obj = new String("0")
console.log(num == obj)
console.log(num == str)
console.log(obj == str)
console.log(null == undefined)
console.log('' == false)
console.log(0 == false)
配置 ESLint:在项目根目录下创建一个 .eslintrc
或 .eslintrc.json
文件,并配置以下规则:
{
"rules": {
"eqeqeq": "error"
}
}
4.不规范命名:
命名方式
苏州话 单词拼写错误: submitFrom submitForm
单复数 不清楚:
commentDatas commentsData
comments commentList commentsList commentsLists
5.使用合适的函数
async function downloadExcelFromAPI(url, fileName) {
try {
const response = await fetch(url);
const blob = await response.blob();
const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = fileName;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
} catch (error) {
console.error('下载文件出错:', error);
}
}
import React, { Component } from 'react';
import { openFile } from '@za/za-utils';
class ModalUpload extends Component {
...
...
...
...
<Form.Item labelCol={{ span: 3, offset: 12 }}>
<Button
type="primary"
disabled={loading || !validatePath}
onClick={() => {
openFile.downloadWithLink(validatePath);
}} >
异常错误下载
</Button>
</Form.Item>
...
...
...
6.适当的三元操作
isSubscribed ? (
<A />
) : isRegistered ? (
<B>
) : (
<C />
)
function D({ subscribed, registered }) {
if (subscribed) {
return <A/>
}
if (registered) {
return <B />
}
return <C />
}
function Component() {
return (
<D
subscribed={subscribed}
registered={registered}
/>
)
}
7.是否引用了不必要的npm包
以下的例子是否需要引入整个 lodash 包
import React from 'react'
import { Button } from 'antd'
import _ from 'lodash'
const QueryBtn = (props) => {
const { btnList } = props
return (
<div>
{btnList.map((item) => {
const { style, isDisabled, onClick, title } = item
return (
<Button
key={title}
size="small"
type="primary"
style={style}
disabled={isDisabled}
onClick={onClick}
>
{title}
</Button>
)
})}
</div>
)
}
export default React.memo(QueryBtn, (prev, next) => {
const toStrPrve = JSON.stringify(prev)
const toStrNext = JSON.stringify(next)
const result = _.isEqual(toStrPrve, toStrNext)
return result
})
其他方案
使用 lodash-es
, lodash-es
采用了按需加载(tree-shaking)的方式,可以更细粒度地导入所需的函数,减小最终构建产物的尺寸。相比之下,lodash
在导入整个库时会包含所有的函数,尺寸较大。
使用子包。
8.逻辑优化,视图层无关的代码
const deleteTagById = async (id) => {
const ids = []
id.forEach((item) => {
ids.push(item)
})
const data = new FormData()
data.append('tagIds', ids)
const res = await deleteTag(data)
if (res?.success) {
message.success('删除成功')
actionRef.current.reload()
}
}
优化后
export const deleteTag = (ids) => {
const data = new FormData();
data.append('tagIds', ids);
return post('/tag/delete', data);
};
9.是否正确使用条件语句来实现期望的代码逻辑?
if (isTrue === true) {
// 执行一些操作
}
// 良好示例
if (isTrue) {
// 执行一些操作
}
function loop(rule, keys) {
const result = rule.rule(value, keys, param)
if (result === false) {
if (typeof onError === 'function') {
onError(
typeof rule.errorMsg === 'function'
? rule.errorMsg(value, keys, param, prevLocation)
: rule.errorMsg,
keys,
value,
prevLocation
)
}
} else if (result === true) {
if (rule.successMsg && typeof onSuccess === 'function') {
onSuccess(rule.successMsg, keys, value, prevLocation)
}
} else {
throw new Error(`${key} must return a value of Boolean!`)
}
return result
}
四 、总结
在CodeReview阶段发现的逻辑错误、业务理解偏差、性能隐患等时有发生,CR可以提前发现问题。
主要体现在代码健壮性、设计合理性、代码优雅性等方面,持续CodeReview可以提升团队整体代码质量。
每一次CodeReview,都是一次知识的分享,磨合一定时间后,团队成员间会你中有我、我中有你,集百家之所长,融百家之所思。同时,业务逻辑都在代码中,团队CodeReview也是一种新人业务细节学习的途径。
通过多次讨论与交流,逐步达成团队共识,特别是对架构理解和设计原则的认知,在共识的基础上团队也会更有凝聚力,特别是在较多新人加入时尤为重要。