React源码调试

最近看了很多react源码的讲解视频、文章,不过纸上得来终觉浅,看一百次不如自己调试一次印象来得深。

拉取react源码安装依赖

js 复制代码
git clone https://github.com/facebook/react.git
yarn

拉取源码后可以看到react的模块都放在packages目录下,因为react的类型检查用的是flow,肯定是不能直接运行在浏览器里的所以我们需要使用babel转换成普通的js。packages下有许多模块有的模块涉及到服务端渲染、开发工具、跨平台,这里我们只需要浏览器相关的模块 react react-client react-dom react-dom-bindings react-reconciler scheduler shared 接下来就可以使用babel转换这些模块,转换的时候会遇到报错有些报错文件并不会转换成功,先不用管,后面启动项目时遇到缺少的文件或目录再一一单独转换就行

js 复制代码
// 这里只举例了react, 上述其他模块也是如此
./node_modules/.bin/babel ./packages/react --out-dir ./build/react

启动项目

  1. 先创建一个react项目,然后把react源码build目录拷到react-debug下改名为react-source。
js 复制代码
pnpm create vite react-debug --template react
  1. 修改vite.config.js
js 复制代码
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    // 修改 jsx 方法的引用路径,会指向到react-source/react/jsx-dev-runtime.js
    react({
      jsxRuntime: "automatic",
      jsxImportSource: path.resolve(import.meta.dirname, "react-source/react/"),
    }),
  ],
  // 定义react中的变量
  define: {
    __EXPERIMENTAL__: false,
    __PROFILE__: false,
    __DEV__: false,
  },
  resolve: {
  // 设置文件系统别名
    alias: [
      {
        find: "react",
        replacement: path.resolve(import.meta.dirname, "react-source/react/"),
      },
      {
        find: /^react-dom\/(.*)?/,
        replacement: path.resolve(
          import.meta.dirname,
          "react-source/react-dom/$1"
        ),
      },
      {
        find: /^react-source\/(.*)?/,
        replacement: path.resolve(import.meta.dirname, "react-source/$1"),
      },
      {
        find: /^react-dom-bindings\/(.*)?/,
        replacement: path.resolve(
          import.meta.dirname,
          "react-source/react-dom-bindings/$1"
        ),
      },
      {
        find: /^shared\/(.*)?/,
        replacement: path.resolve(
          import.meta.dirname,
          "react-source/shared/$1"
        ),
      },
      {
        find: /^react-reconciler\/(.*)?/,
        replacement: path.resolve(
          import.meta.dirname,
          "react-source/react-reconciler/$1"
        ),
      },
      {
        find: "scheduler",
        replacement: path.resolve(
          import.meta.dirname,
          "react-source/scheduler/"
        ),
      },
      {
        find: /^react-client\/(.*)?/,
        replacement: path.resolve(
          import.meta.dirname,
          "react-source/react-client/$1"
        ),
      },
    ],
  },
});
  1. 修改 react/src/jsx/ReactJSX.js。(PS: 可能会因为在第一步执行babel失败在react-source中并没有jsx目录,再到react源码中执行 ./node_modules/.bin/babel ./packages/react/src/jsx --out-dir ./build/react/src/jsx然后再把jsx目录复制到react-source就行了,其他babel执行失败的文件也是一样 )
js 复制代码
// react-source/react/src/jsx/ReactJSX.js 
var jsxDEV = __DEV__ ? _jsxDEV : jsxProd
  1. 把引入路径都成从 react-source 中引入
js 复制代码
// App.jsx
import { useState } from "react-source/react"

function App() {
  const [count, setCount] = useState(0)
  return (
    <div>
      I am React
      <button onClick={() => {
        setCount(count + 1)
      }}>{count}</button>
    </div>
  )
}

export default App
  1. 最后就可以开始"愉快"得调试源码啦,现在在createRoot的地方打断点就会进到react-source里了
相关推荐
黄智勇10 分钟前
xlsx-handlebars 一个用于处理 XLSX 文件 Handlebars 模板的 Rust 库,支持多平台使
前端
brzhang1 小时前
为什么 OpenAI 不让 LLM 生成 UI?深度解析 OpenAI Apps SDK 背后的新一代交互范式
前端·后端·架构
brzhang2 小时前
OpenAI Apps SDK ,一个好的 App,不是让用户知道它该怎么用,而是让用户自然地知道自己在做什么。
前端·后端·架构
水冗水孚2 小时前
React中使用map+area标签实现img图片特定区域标记功能(可用Photoshop精准拾取对应点位)
react.js·html·photoshop
井柏然3 小时前
前端工程化—实战npm包深入理解 external 及实例唯一性
前端·javascript·前端工程化
IT_陈寒3 小时前
Redis 高性能缓存设计:7个核心优化策略让你的QPS提升300%
前端·人工智能·后端
井柏然3 小时前
从 npm 包实战深入理解 external 及实例唯一性
前端·javascript·前端工程化
羊锦磊4 小时前
[ vue 前端框架 ] 基本用法和vue.cli脚手架搭建
前端·vue.js·前端框架
brzhang4 小时前
高通把Arduino买了,你的“小破板”要变“AI核弹”了?
前端·后端·架构
她说..4 小时前
通过git拉取前端项目
java·前端·git·vscode·拉取代码