yanyue404/blog

debug 调试技术指北

Opened this issue · 0 comments

前言

你的 debug 姿势够娴熟吗?

如何减少 bug?或者可以换一个问题,怎样快速 fix bugs?

编码

  • 项目结构清晰合理
  • 组件化解耦
  • 编码的健壮性,适应 1、2,还有...
  • 全局状态的管理维护
  • 异常边界值考虑,try ... catch
  • 为项目工具函数与组件编写单元测试用例

工程化流程

  • 静态代码检查
  • 提交前预处理修复
  • 单元测试警报
  • 分支管理策略

目录

开发阶段

开发场景为 vue 或 react 为主的单页面应用。

Chrome DevTools

  • Vue.js devtools
  • React Developer Tools

Source Map 调试

开启 source-map 的配置将会在本地以及发布后的线上生效,使用 Chrome 浏览器访问 后 Source 面板下的 webpack:// 可以找到 Project 源码进行断点调试,就是在 asyncawait语法中也能精准定位。

config.devtool = "eval-source-map"; //需要时才放开

重要提醒:修改好 bug 后务必及时关闭 source-map 并再次发布,以防源码泄露。

Vscode 调试

首先安装 Debugger for Chrome 插件,配置好launch.json

// launch.json
{
  // 使用 IntelliSense 了解相关属性。
  // 悬停以查看现有属性的描述。
  // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "启动程序",
      "url": "http://localhost:9009",
      "webRoot": "${workspaceRoot}/src"
    }
  ]
}

然后启动项目, yarn dev, 等待项目成功启动提示:

<s> [webpack.Progress] 100%

  App running at:
  - Local:   http://localhost:9009/
  - Network: http://10.64.101.37:9009/

F5 开启调试模式,打断点,继续 debug。如果出现 Breakpoint set but not yet bound说明 设置断点但尚未绑定, 可以强制使用 debugger 确保准确断点定位。

代理调试

面临的使用场景:

  • 后端接口微服务
  • 公众号必须使用线上 token 且与后端本地物理机不通用
  • 前后端联调场景

调试方案 :大部分接口使用线上服务,部分接口代理至本地物理机独立的服务模块调试

原先全部使用线上:

// http.js
axios.defaults.baseURL = "/prod-api";

// vue.config.js
module.exports = {
  proxy: {
    [process.env.VUE_APP_BASE_API]: {
      target: `http://h5.baishi360.cn/`,
      changeOrigin: true,
      pathRewrite: {
        "^/api": "",
      },
    },
  },
};

部分接口代理到本地:

// http.js
axios.defaults.baseURL = "";

// vue.config.js
module.exports = {
  proxy: {
    // 本地代理 1 保险公司 险种信息查询
    "/api-inslife/api/ins/company/getCompanyWithProduct": {
      target: `http://172.16.1.103:18013/`, // api-inslife
      changeOrigin: true,
      pathRewrite: {
        "^/api-inslife": "",
      },
    },
    // 本地代理 2 代理人计划书相关
    "/api-agt/agt/planBook/saveAgtPlanInfo": {
      target: `http://172.16.1.103:18010/`, // api-agt
      changeOrigin: true,
      pathRewrite: {
        "^/api-agt": "",
      },
    },
    // 线上代理
    "": {
      target: `http://h5.baishi360.cn/prod-api/`,
      changeOrigin: true,
    },
  },
};

生产环境

A lightweight, extendable front-end developer tool for mobile web page.

Console for mobile browsers

  • fiddler 抓包调试

推荐操作资料:Fiddler “抓包“最新详细教程

辅助工具:Proxy SwitchyOmega - 轻松快捷地管理和切换多个代理设置

操作步骤:参照上面的资料进行,我的关键步骤截图在这里(ip: 172.16.1.141)

注意项:在移动端真机调试的时候需要勾选 Allow remote computers to connect

微信调试,各种 WebView 样式调试、手机浏览器的页面真机调试。便捷的远程调试手机页面、抓包工具,支持:HTTP/HTTPS,无需 USB 连接设备。

移动端调试工具预留

Eruda || vConsole

方案 1:

实现效果:

  1. NODE_ENV 为 development 模式时开启 debug 模式
  2. NODE_ENV 为 production 模式时可手动开启(与关闭)debug 模式 (通过预留的点击后门)
  3. 跳转的页面添加 debug=true URL 参数可以打开调试模式
  • public/index.html
<script>
  (function () {
    var ENV = sessionStorage.getItem("ENV");
    console.log("ENV:", ENV);
    var src = "";

    if (
      ENV == "development" ||
      localStorage.getItem("debug") === "true" ||
      /debug=true/.test(window.location)
    ) {
      src = "https://cdn.bootcss.com/vConsole/3.3.0/vconsole.min.js";
    }
    // FIX: Uncaught TypeError: VConsole is not a constructor
    if (ENV) {
      document.write("<scr" + 'ipt src="' + src + '"></scr' + "ipt>");
      document.write(
        "<scr" + "ipt> var VConsole = new VConsole();</scr" + "ipt>"
      );
    }
  })();
</script>
  • main.js
sessionStorage.setItem("ENV", process.env.NODE_ENV);

// 如果重定向后需要开启 debug 就不用关闭了
localStorage.getItem("debug") === "true"
  ? ""
  : localStorage.setItem("debug", false);
  • home.vue
// 点击规则详情10次就可以唤起 debug 模式了,再点击10次就关闭 debug 模式
var count = 0;
const showDebug = () => {
  if (count >= 10) {
    var debug = localStorage.getItem("debug");
    console.log("debug", debug);
    if (!debug || debug === "false") {
      localStorage.setItem("debug", "true");
    } else {
      localStorage.setItem("debug", "false");
    }
    count = 0; // 清零
    location.reload(); // 重载
  }
  count++;
};

方案 2:

// 依托环境变量注入
{{ ENV.PATH_TYPE === "production" ? `` :  `<script src="https://cdn.bootcss.com/vConsole/3.3.0/vconsole.min.js></script>`}} 

// app.html
 <script>
      if(location.href.indexOf('?vconsole=true') > 0) {
          var sc = document.createElement('script');
          sc.src="https://cdn.bootcss.com/vConsole/3.3.0/vconsole.min.js";
          document.head.insertBefore(sc, document.head.firstChild);
      }
  </script>

方案 3:推荐

Whistle ,参见 使用教程

Node

Inspector 原理

  • WebSockets 服务(监听命令)
  • Inspector 协议
  • Http 服务(获取元信息)

Chrome DevTools

  • 访问 chrome://inspect,点击配置按钮,确保 Host Port 正确,然后点击 下方inspect按钮进入调试页面,打上断点后,在浏览器窗口打开监听的原始端口即可调试
  • 借助 vscode 打印的端口号 (node --inspect app.js)访问端口 localhost:9229/json获取元信息,在浏览器中访问 devtoolsFrontendUrl
  • 在 chrome http://localhost:3000/打开开发者页面,选择 Elements元素按钮左侧的 Node.js图标,可进入调试页面

参考资料