您的位置:首页 > Web前端 > React

React源码下载-本地环境搭建

2020-08-20 13:48 831 查看

前几天有小伙伴和我聊天,谈到现在前端面试越来越难,动不动就是xxx原理,有没有看过xx源码之类的问题, 之后就问我应该怎么来学习现在主流框架的源码,于是有了这一篇文章.

说到使用react那很简单 react 和reactdom 两个文件引入一下就ok,但是这两个文件是经过编译打包,我们无法在里面进行断点调试或者console调试, 所以想学习框架源码,第一步就要在本地运行源码这样才能在内部进行各种输出调试。

好了闲话不说,直接开始正题

React源码获取

在这里我选择用的的版本是16.10.0 , 获取方式当然是react的git仓库

创建测试项目

  • 在本地通过create-react-app创建测试项目
  • 创建完项目之后要修改源码以及webopack配置,需要 将‘旺旺大礼包’给解出来 npm run eject
  • 项目目录下会多出一个config文件

 

 

将创建的项目替换为下载的源码文件

  • 将下载16.10.0的项目源码丢到src目录下

 

 

  • 更改配置文件 ==/config/webpack.config.js== 在运行项目的时候编译我们导入的源码为
[code]    resolve:{
...,
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
// 'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
// ...(isEnvProductionProfile && {
//   'react-dom$': 'react-dom/profiling',
//   'scheduler/tracing': 'scheduler/tracing-profiling',
// }),
// ...(modules.webpackAliases || {}),
'react': path.resolve(__dirname, '../src/react/packages/react'),
'react-dom': path.resolve(__dirname, '../src/react/packages/react-dom'),
'legacy-events': path.resolve(__dirname, '../src/react/packages/legacy-events'),
'shared': path.resolve(__dirname, '../src/react/packages/shared'),
'react-reconciler': path.resolve(__dirname, '../src/react/packages/react-reconciler'),
},
}
错误处理

替换完成后,因为版本和编译的原因会遇到各种错误, 具体的错误类型与解决方式,在这里做一个简单的介绍

flow 检测报错

 

 

  • 由于react的源码中采用了flow这个东东做类型检查, 所以我们需要安装 ==@babel/plugin-transform-flow-strip-types== 这个插件忽略类型检测
  • 插件安装
[code]npm install @babel/plugin-transform-flow-strip-types -D
  • 插件配置
[code]   //在webpack.config.js的babel-loader中添加配置
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),

plugins: [
...,
[require.resolve('@babel/plugin-transform-flow-strip-types')]
// 配置忽略flow类型检测
],
...
}

HostConfig配置错误

 

 

  • 修改文件 ==src/react/packages/react-reconciler/src/ReactFiberHostConfig.js==, 根据环境去导出HostConfig。
[code]//添加以下代码
export * from './forks/ReactFiberHostConfig.dom';

部分全局变量报错

 

 

  • 修改 ==/config/env.js== 中的stringifed对象增加属性
[code]  const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
"__DEV__": true,
"__PROFILE__": true,
"__UMD__": true
};

hasOwnProperty ReactSharedInternals.js错误

 

 

  • 修改文件 ==src/react/packages/shared/ReactSharedInternals.js。==
[code]// react此时未export内容,直接从ReactSharedInternals拿值
// import React from 'react';
// 此时React为undefined
// const ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
​
import ReactSharedInternals from '../react/src/ReactSharedInternals';

invariant() 函数报错

 

 

  • ==src/react/packages/shared/invariant.js== 文件下 invariant 函数的错误处理
  • 修改如下:
[code]export default function invariant(condition, format, a, b, c, d, e, f) {
if(condition) return ;
throw new Error(
'Internal React error: invariant() is meant to be replaced at compile ' +
'time. There is no runtime version.',
);
}
​

到此为止现在运行的react项目采用的使我们下载导入的react16.10.0的源码,我们就可以在源码里进行输出的错误调试

比如我在react/index.js源码 进行输出测试

[code]'use strict';
​
const React = require('./src/React');
console.log('源码测试',React)
// TODO: decide on the top-level export form.
// This is hacky but makes it work with both Rollup and Jest.
module.exports = React.default || React;

 

 

嫌弃本地测试环境配置太麻烦的话,各位小主可以直接从下面的地址拉取我配置好的开发项目

https://github.com/fchangjun/ReactSourceCodeAnalyze.git

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: