深入React(1)调试React源码

想要深入学习React底层知识,充实自己(为了面试~),还是得看看源码才有底气。推荐一个国外小哥的博客&视频:React Internals Deep Dive。不过磨刀不误砍柴工,在正式开始前,我们得看看如何调试React源码。

准备工作

调试前我们需要先准备好调试使用的代码。有两种方式:从源码构建(推荐)或使用已发布的React包。

从源码构建

参考React官方文档:development-workflow。

shell 复制代码
# 克隆
$ git clone https://github.com/facebook/react.git

# 安装依赖
$ cd react & yarn

# 构建
$ yarn build react/index,react-dom/index --type=UMD

构建完成后,打开fixtures/packaging/babel-standalone/dev.html文件,其中引用的即是刚才构建好的React。

html 复制代码
<html>
  <body>
    <script src="../../../build/oss-experimental/react/umd/react.development.js"></script>
    <script src="../../../build/oss-experimental/react-dom/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
    <div id="app"></div>
    <script type="text/babel">
      const container = document.getElementById('app');
      const root = ReactDOM.createRoot(container);
      root.render(<h1>Hello World!</h1>);
    </script>
  </body>
</html>;

解释下代码里的"text/babel":babel会在DOM加载完成时检测"text/babel"类型的脚本,并转换代码后执行,从而支持直接编写JSX。sricpt标签类型为type="text/babel"时,其内部代码是不会被浏览器执行的。

使用已发布的React包

只需将React链接修改为已发布的链接即可。

html 复制代码
<html>
  <body>
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
    <div id="app"></div>
    <script type="text/babel">
      const container = document.getElementById('app');
      const root = ReactDOM.createRoot(container);
      debugger;
      root.render(<h1>Hello World!</h1>);
    </script>
  </body>
</html>;

开始调试

在准备好代码之后,我们就可以着手开始调试了。调试可以用浏览器(推荐Chrome)开发者工具,也可以用VSCode,选择个人熟悉的即可,也可以各取所长。

浏览器开发者工具

在调试前,我们可以通过开发者工具的Performance面板查看完整的运行过程。效果如下:

点击函数可以查看源码位置:

下一步我们即可以在Sources面板的源码中打断点调试。

或者直接在代码中添加debugger:

jsx 复制代码
const container = document.getElementById('app');
const root = ReactDOM.createRoot(container);
debugger; // 程序将停止在这里
root.render(<h1>Hello World!</h1>);

VSCode

VSCode也支持调试网页代码。第一步在左侧调试面板中点击新建launch.json文件,内容如下,将url改为网页地址或文件地址即可。

接着在react-dom.development.js文件中打上断点。

最后一步,点击左侧调试面板的Start Debugging启动调试。

一些调试小技巧

一般调试都有这几个按钮,以VSCode为例:

  1. Continue。前往下一个断点。
  2. Step Over 。一次执行完一条语句 。比如执行一个函数const num = Math.sqrt(2,2),如果你不想进入Math.sqrt里查看细节,只想看到执行完的结果,那么就用Step Over。反之,如果你想看Math.sqrt里是如何实现的,则点击下面的Step Into。
  3. Step Into 。将会进入函数,一行一行执行。比如const num = Math.sqrt(2,2),点击Step Into后点会进入到Math.sqrt内部。
  4. Step Out。与Step Into对应。执行后将会跳出当前执行的函数。
  5. Restart。终止当前程序执行并重启调试。
  6. Stop。终止当前程序执行。

下面是一些常用的提高调试效率的小技巧:

善用Step Over

不是每个地方都需要Step Into来一行一行的调试,这时候使用Step Over,省略过程,快速获取结果就行。

遇到回调函数怎么办?

对于回调函数这种异步代码,我们无法通过Step Over或Step Into来跳转到指定处执行。

csharp 复制代码
this.hooks.beforeCompile.callAsync(params, err => {
  // 把断点打在回调函数里,点击Continue!
  const compilation = this.newCompilation(params);
  // ...
});

这时只需直接将断点打在回调函数里,点击Continue(前往下一个断点)即可。

不小心错过了想要调试的那一行?

直接将断点打在前面想要调试的那一行,点击Restart。

如何查看调用栈?

如果一个程序逻辑比较绕,回调比较多,梳理不清楚执行过程,可以查看调用栈来帮助分析。


相关推荐
福兮说2 小时前
前端下载大文件,点了按钮半天没反应:fetch + blob 的三个问题和三种替代写法
前端·javascript·性能优化·文件下载
GreenTea2 小时前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
科技观察哨3 小时前
六足平台选型与纳米定位系统集成:HEB-640六自由度位移台在半导体光刻对准中的参数边界与国产替代评估
前端·人工智能
落魄大学生之流水线上谋生计3 小时前
Remotion:用 React 写视频,让代码成为剪辑师
react.js
niucloud-admin3 小时前
JAVA V6 多商户商城 开发文档——web前端
前端
颜进强3 小时前
16 · NestJS LifecycleEvents 生命周期事件:五个钩子、三条边界,和 rag-server 的优雅停机
前端·后端·ai编程
今年下半年5 小时前
【VUE】整合腾讯地图、自定义区域边界、村委名称及资产统计(放大显示资产点位)
前端·javascript·vue.js
郑州光合科技余经理5 小时前
同城电商系统:库存变更怎么同步到订单
java·开发语言·前端·后端·uni-app·php·ai编程
前端snow7 小时前
ai agent --- DeepAgents 中间件
前端
data analyse 4567 小时前
报表能自定义的国内统计工具有哪些
前端·数据分析