使用webpack搭建react源码调试环境

参考:
https://www.jianshu.com/p/0bdd1950ee5b
https://www.bilibili.com/video/BV1Q34y1m7Cq

从GitHub拉取react代码,采用的react-17.0.1版本,关于web端的核心源码,在packages文件夹中的

react, react-dom, react-reconciler, scheduler, shared, 我们只需要这些文件

整个项目目录
使用webpack搭建react源码调试环境_第1张图片

使用webpack搭建调试环境(webpack.config.js文件)

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");
module.exports = {
	entry: "./src/index.js",
	mode: "development",
	devtool: "source-map",
	devServer: {
		port: 9000,
	},
	module: {
		rules: [
			{
				test: /.(js)|(jsx)$/,
				use: {
					loader: "babel-loader",
					options: {
						presets: ["@babel/preset-flow"],
					},
				},
			},
		],
	},
	devServer: {
		port: "9999",
		host: "localhost",
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: "./public/index.html",
		}),
		new webpack.DefinePlugin({
			__DEV__: true,
			__PROFILE__: true,
			__EXPERIMENTAL__: true,
			__UMD__: true,
		}),
	],
	resolve: {
		alias: {
			react: path.resolve(__dirname, "./packages/react"),
			shared: path.resolve(__dirname, "./packages/shared"),
			scheduler: path.resolve(__dirname, "./packages/scheduler"),
			"react-dom": path.resolve(__dirname, "./packages/react-dom"),
			"react-reconciler": path.resolve(
				__dirname,
				"./packages/react-reconciler"
			),
		},
	},
};

安装所需要的依赖(package.json文件)

直接复制到package.json文件中,然后yarn
或者根据包名,自己执行yarn add xxx xxx

{
	"name": "react_code",
	"version": "1.0.0",
	"main": "index.js",
	"license": "MIT",
	"scripts": {
		"start": "npx webpack serve"
	},
	"dependencies": {
		"@babel/core": "^7.18.2",
		"@babel/preset-flow": "^7.17.12",
		"@babel/preset-react": "^7.17.12",
		"babel-loader": "^8.2.5",
		"html-webpack-plugin": "^5.5.0",
		"webpack": "^5.73.0",
		"webpack-cli": "^4.9.2",
		"webpack-dev-server": "^4.9.1"
	},
	"devDependencies": {
		"object-assign": "^4.1.1"
	}
}

修改babel配置 ( .babelrc文件)

{
	"presets": ["@babel/preset-react"]
}

修改相关文件源码

  1. packages/react-reconciler/src/ReactFiberHostConfig.js
    // invariant(false, 'This module must be shimmed by a specific renderer.');
    export * from "./forks/ReactFiberHostConfig.dom";
    
  2. packages/react-reconciler/src/ReactFiberWorkLoop.new.js和packages/react-reconciler/src/ReactFiberWorkLoop.old.js
    // import * as Scheduler from 'scheduler';
    import * as Scheduler from "scheduler/unstable_mock";
    
  3. packages/shared/ReactSharedInternals.js
    // import * as React from 'react';
    
    // const ReactSharedInternals =
    //   React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
    import ReactSharedInternals from "../react/src/ReactSharedInternals";
    
    export default ReactSharedInternals;
    
  4. packages/shared/invariant.js
    export default function invariant(condition, format, a, b, c, d, e, f) {
    	// 添加一个if判断语句
    	if (condition) return;
    	throw new Error(
    		"Internal React error: invariant() is meant to be replaced at compile " +
    			"time. There is no runtime version."
    	);
    }
    
  5. packages/scheduler/src/SchedulerHostConfig.js
    // throw new Error('This module must be shimmed by a specific build.');
    export * from "./forks/SchedulerHostConfig.default";
    
  6. packages/scheduler/unstable_mock.js
    // from './src/SchedulerHostConfig.js'; // 引入路径替换成下面的
    export {
    	xxxx
    } from "./src/forks/SchedulerHostConfig.mock";
    // 
    

修改入口文件引入react方式

// ============================================
import * as React from "react";
import * as ReactDOM from "react-dom";
// ============================================
function App(props) {
	const [count, setCount] = React.useState(0);
	return (
		<h1
			onClick={(e) => {
				setCount(666);
			}}
		>
			chenjiang{count}
		</h1>
	);
}
ReactDOM.render(<App />, document.getElementById("root"));

项目地址

你可能感兴趣的:(webpack,#,React学习,javascript,webpack)