Skip to content

debugger

Github 地址

react-debugger

创建项目

1. vite 创建 react 项目

bash
yarn create vite react-debugger --template react

2. 下载 react 最新源码

js
// 下载时间为 20230720 react 版本为 "version": "18.2.0"
git clone https://github.com/facebook/react.git

3. 将 react 源码中的包移动到我们的项目中 src/react/packages/xxx

js
// 需要移动的包
react
react - dom
react - dom - bindings
react - reconciler
scheduler
shared

4. 配置 vite.config.js

增加别名和环境变量,如下:

js
import path from 'node:path'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    // 配置别名
    alias: {
      'react': path.posix.resolve('src/react/packages/react'),
      'react-dom': path.posix.resolve('src/react/packages/react-dom'),
      'react-dom-bindings': path.posix.resolve(
        'src/react/packages/react-dom-bindings'
      ),
      'react-reconciler': path.posix.resolve(
        'src/react/packages/react-reconciler'
      ),
      'scheduler': path.posix.resolve('src/react/packages/scheduler'),
      'shared': path.posix.resolve('src/react/packages/shared'),
    },
  },
  // 配置环境变量,解决__DEV__ is not defined
  define: {
    __DEV__: false, // 设置为false跳过 if(__dev__)的开发逻辑 这样会报错 需要修改jsx_dev的引入
    __EXPERIMENTAL__: true,
    __PROFILE__: true,
  },
})

如果要设置__DEV__为 false,需要调整以下代码:

js
// src/react/packages/react/src/jsx/ReactJSX.js
// 修改后

import { REACT_FRAGMENT_TYPE } from 'shared/ReactSymbols'
import {
  jsxWithValidation,
  jsxWithValidationDynamic,
  jsxWithValidationStatic,
} from './ReactJSXElementValidator'
import { jsx as jsxProd } from './ReactJSXElement'
const jsx = __DEV__ ? jsxWithValidationDynamic : jsxProd
// we may want to special case jsxs internally to take advantage of static children.
// for now we can ship identical prod functions
const jsxs = __DEV__ ? jsxWithValidationStatic : jsxProd
// const jsxDEV      = __DEV__ ? jsxWithValidation : undefined; // 隐藏

const jsxDEV = jsxProd // 增加

export { REACT_FRAGMENT_TYPE as Fragment, jsx, jsxs, jsxDEV }

如果需要配置未生效时,可以尝试删除node_modules/.vite文件夹,重新启动项目

react 包移动完成后目录如下:

Preview

5. 配置 jsconfig.json

js
// 给vscode编辑器使用2024-09-29_11-20-
{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "react/*": ["src/react/packages/react/*"],
      "react-dom/*": ["src/react/packages/react-dom/*"],
      "react-dom-bindings/*": ["src/react/packages/react-dom-bindings/*"],
      "react-reconciler/*": ["src/react/packages/react-reconciler/*"],
      "scheduler/*": ["src/react/packages/scheduler/*"],
      "shared/*": ["src/react/packages/shared/*"]
    }
  },
  "exclude": ["node_modules", "dist"]
}

6. 开启 debugger

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

7. 启动项目

js
npm run dev

yarn dev

处理报错

1. import type {ReactNodeList} from 'shared/ReactTypes';

报错如下:

Preview

解决办法:

  • 安装 flow-remove-types
js
yarn add flow-remove-types -D
  • 执行命令
js
npx flow-remove-types --out-dir src/react src/react

执行完成后,如下:

Preview

2. No matching export in "src/react/packages/react-dom/client.js" for import "default"

报错如下:

Preview

解决办法: 查看 client 文件是 export 到处的,所以需要修改引入方式

js
import * as React from 'react'
// import React from "react";
import * as ReactDOM from 'react-dom/client'
// import ReactDOM from "react-dom/client";
import App from './App.tsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)

3. The requested module '/src/react/packages/react-reconciler/src/ReactFiberConfig.js' does not provide an export named 'getChildHostContext'

报错如下:

Preview

解决办法 src/react/packages/react-reconciler/src/ReactFiberConfig.js 更改后如下:

js
// src/react/packages/react-reconciler/src/ReactFiberConfig.js

/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 *
 */

// We expect that our Rollup, Jest, and Flow configurations
// always shim this module with the corresponding host config
// (either provided by a renderer, or a generic shim for npm).
//
// We should never resolve to this file, but it exists to make
// sure that if we *do* accidentally break the configuration,
// the failure isn't silent.

// throw new Error('This module must be shimmed by a specific renderer.');

// 引入文件
export * from './forks/ReactFiberConfig.dom-browser'

// 其实就是
// export * from 'react-dom-bindings/src/client/ReactDOMHostConfig';

上述问题解决后,就可以正常调试了

Preview