为了更深入的学习react源码,直接进行断点调试是一个不错的手段。因此,我们需要搭建一个调试环境。
- 下载源码
首先,我们从github上把源码down下来。react源码在github的地址为 直接git clone
down下来之后,我们可以看一下源码结构。其中src目录下的package文件中就是react源码。react是用learna多包管理工具进行管理的。其中比较核心的package有react,reactDom,react-conciler。
- 搭建本地环境
这里我们打算用webpack来搭建我们调试的本地环境。npm init 后,直接在目录下创建webpack.config.js配置文件。
module.exports = {
entry: './src/index.jsx',
mode: 'development',
devtool: 'source-map',
devServer: {
port: 9000
},
module: {
rules: [
{
test: /.(js)|(jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
},
devServer: {
port: '3300',
host: 'localhost',
client: {
overlay: {
errors: true,
warnings: false,
},
}
},
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'),
}
}
}
下载一系列依赖webapck,webpack-cli,webpack-dev-server,@babe/core,@babel/preset-react, @babel/preset-flow, html-webpack-plugin这里因为react源码采用的是flow规范,因此我们需要下载@babel/preset-flow预设。
项目的目录结构如下
其中babel配置如下
module.exports = {
presets: [
require.resolve('@babel/preset-react'), // 转换jsx语法
require.resolve('@babel/preset-flow')
]
}
目录中的package目录下就准备放我们的react源码。
3.引入react源码
将源码中的react react-dom react-reconciler scheduler shared这五个包拷贝到项目的package目录中。
4.修改react源码
看似大功搞成,但是这样直接启动是会报错的。这是因为react源码是用rollup打包的,我们需要对源码做一些修改。
1.修改 src\packages\react-reconciler\src\ReactFiberHostConfig.js, 导出HostConfig
// import invariant from 'shared/invariant';
// invariant(false, 'This module must be shimmed by a specific renderer.');
export * from './forks/ReactFiberHostConfig.dom'
2.修改 src\react\packages\shared\ReactSharedInternals.js
// import React from 'react';
// const ReactSharedInternals =
// React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
import ReactSharedInternals from '../react/src/ReactSharedInternals'
- 启动项目
npm start启动项目后,直接在render函数处打断点就可以看到react组件渲染的调用栈了