前端code review

一、为啥要 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-eslodash-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也是一种新人业务细节学习的途径。
通过多次讨论与交流,逐步达成团队共识,特别是对架构理解和设计原则的认知,在共识的基础上团队也会更有凝聚力,特别是在较多新人加入时尤为重要。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web面试那些事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值