【在开发小程序的时候如何排查问题】

在开发小程序的时候如何排查问题

在最近开发小程序的时候,经常出现本地在浏览器中调试没有问题,但是一发布到预发环境就出现各种个样的问题

  1. 手机兼用性问题

    js 复制代码
    有时候会出现苹果🍎手机键盘弹出,导致ui界面高度出现异常
  2. 边界问题,导致js报错

    js 复制代码
    小程序页面出现白屏,可能是js报错,但是我们没办法像在浏览器中一样去打开控制台查看日志报错信息
    但是自己本地又复现不了
  3. 后端接口报错

js 复制代码
 有时候新增/修改调用后端接口的时候,后端接口可能会对字段进行校验,抛出错误信息,
 说你某个字段传递的有问提,但是我们无法真正捕获到有用的信息,比如这个字段传递给后端的时候到底是怎样的,
 有时候不得不麻烦后端同学去查看一下后端接口的日志信息,每次这样去找后端,也是会被讨厌的不是吗。

所以,作为前端的小伙伴我们应该怎样处解决小程序开发中所出现的问题呢?

我们这边以react开发小程序为例

  1. 面对js报错问题,我们可以开发一下 ErrorBoundary 组件,在组件内部捕获js报错,并在页面上展示错误信息
    不管是在开发环境还是在生产环境,这个组件都能很好的帮助开发者排查前端问题。

ErrorBoundary 原理使用 react 类组件中的 componentDidCatch生命周期 进行错误的捕获,如果有错误信息则展示错误信息否则展示正常的页面

js 复制代码
  
import React from "react";
import styles from "./index.less";
import { Toast } from "antd-mobile";

class ErrorBoundary extends React.Component<any,{ hasError: boolean; errorInfo: string }> {
  constructor(props) {
    super(props);
    this.state = { hasError: false, errorInfo: null };
  }

  static getDerivedStateFromError(error) {
    // 更新状态使得下一次渲染能够显示降级后的UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 你同样可以将错误日志上报给服务器
    const url = location.href;
    this.setState({ errorInfo: `${error.toString()}\n当前地址:${url}` });
  }

  render() {
    /* 复制去反馈 */
    const onCopy = () => {
      navigator.clipboard.writeText(this.state.errorInfo);
      Toast.show({
        content: "复制成功",
      });
    };

    if (this.state.hasError) {
      // 你可以渲染任何自定义的降级UI
      return (
        <div className={styles.errorBoundary}>
          <h2>哦呦,出错啦</h2>
          <p>{this.state.errorInfo}</p>
          <div onClick={onCopy} className={styles.errorBoundaryFooter}>
            复制去反馈
          </div>
        </div>
      );
    }

    return this.props.children;
  }
}

export default ErrorBoundary;

ps: 样式可以自行定义

  1. 我们有时候前端打印了很多日志,想去排产问题或者查看数据格式,但是我们无法在浏览器中打开控制台查看,我们怎么去排查呢?

不推荐,但是可用 思路:实现一个react组件,该组件可以配置在最外层,则他的子组件里的所有原生的console方法,都会被重写,重写的console方法会自动收集打印的日志内容,并将内容存储起来,然后在ui中呈现出来

实现结果

js 复制代码
//index.jsx
 import React, { createContext, useContext, useState, useEffect } from "react";

// 创建一个日志上下文
const LogContext = createContext(null);

// 创建一个高阶组件来提供日志收集功能
export const LogProvider = ({ children }: any) => {
  const [logs, setLogs] = useState([]);
  console.log(logs, "logs");
  // 存储原生 console 方法
  const consoleMethods = {} as any;

  useEffect(() => {
    // 重写 console 方法
    Object.keys(console).forEach((method: any) => {
      if (typeof console[method] === "function") {
        consoleMethods[method] = console[method];

        console[method] = (...args) => {
          /* 阻止打印日志logs的时候添加到集合中 */
          if (!args.toString().includes("logs") && logs?.length <= 100) {
            setLogs((prevLogs) => [...prevLogs, { method, args }]);
          }
          consoleMethods[method](...args);
        };
      }
    });

    // 清理函数,恢复原生 console 方法
    return () => {
      Object.keys(console).forEach((method) => {
        if (consoleMethods[method]) {
          console[method] = consoleMethods[method];
        }
      });
    };
  }, []);

  // 提供日志和日志收集状态
  return (
    <LogContext.Provider value={{ logs, setLogs }}>
      {children}
    </LogContext.Provider>
  );
};

// 创建一个自定义 Hook 来访问日志上下文(可选)
export const useLogs = () => useContext(LogContext);
js 复制代码
//  LogViewer.jsx
import React from "react";
import { useLogs } from "./index"; // 请根据实际文件路径调整
import _ from "lodash";
import JsonView from "react18-json-view";
import "react18-json-view/src/style.css";
import RedBox from "redbox-react";

const LogViewer = () => {
  const { logs } = useLogs();
  return (
    <div>
      <h3>Log Viewer</h3>
      <ul
        style={{
          maxHeight: "300px",
          overflowY: "scroll",
          background: "#f0f0f0",
          padding: "1rem",
          border: "1px solid #ddd",
        }}
      >
        {logs.map((log: any, index: any) => (
          <li key={index}>
            <strong>{log.method}</strong>:{" "}
            {log.args.map((arg: any) => {
              if (_.isObject(arg)) {
                return <JsonView src={arg} />;
              } else {
                return arg.toString();
              }
            })}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default LogViewer;

使用方式

js 复制代码
// 在最外层使用
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { LogProvider } from "./components/LogTools/index.tsx";
import LogViewer from "./components/LogTools/LogViewer.tsx";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  <React.StrictMode>
    <LogProvider>
      <LogViewer />
      <App />
    </LogProvider>
  </React.StrictMode>
);

ps: 最好做一个悬浮的工具按钮,让其悬浮固定在页面某个位置,点击查看日志即可

  1. 如何收集查看日志/网络请求等关键信息,当然也可以重新二次封装我们的请求,但是这件事请已经有人帮我们做了有一个公共的npm库
    Mdebug
    安装: npm install --save-dev mdebug 测试环境/预发环境使用、别上生产环境
    使用: 在我们的项目主文件中main.tsx中直接引用即可
js 复制代码
import mdebug from "mdebug";
mdebug.init();

效果图:

相关推荐
计算机徐师兄5 小时前
Java基于SSM框架的无中介租房系统小程序【附源码、文档】
java·微信小程序·小程序·无中介租房系统小程序·java无中介租房系统小程序·无中介租房微信小程序
源码哥_博纳软云5 小时前
JAVA智慧养老养老护理帮忙代办陪诊陪护小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
说私域5 小时前
私域电商逆袭密码:AI 智能名片小程序与商城系统如何梦幻联动
人工智能·小程序
说私域16 小时前
无人零售及开源 AI 智能名片 S2B2C 商城小程序的深度剖析
人工智能·小程序·零售
Kika写代码1 天前
【微信小程序】页面跳转基础 | 我的咖啡店-综合实训
服务器·微信小程序·小程序
源码哥_博纳软云1 天前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络1 天前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
YUJIAN。1 天前
使用uniapp开发微信小程序-框架搭建
微信小程序·小程序·uni-app
关你西红柿子1 天前
小程序app封装公用顶部筛选区uv-drop-down
前端·javascript·vue.js·小程序·uv
V+zmm101341 天前
基于小程序宿舍报修系统的设计与实现ssm+论文源码调试讲解
java·小程序·毕业设计·mvc·ssm