🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
上一篇【react原理实践】使用babel手搓探索下jsx的原理 我们简单讲解了下jsx语法、基本使用、jsx的转换流程、jsx为什么被提到了运行时、和一些简单的源码片段,并使用babel插件简单模拟了下jsx的转换流程。本篇我们将搭建react调试环境,并直接使用源码探究jsx的转换流程。
调试效果
🥑 你能学到什么?
注意本篇调试的是
react18.2.0,使用的是node16!!!
希望在你阅读本篇文章之后,不会觉得浪费了时间。如果你跟着读下来,你将会学到:
- react调试环境搭建原理,这里并不会手把手教你搭建,因为很浪费时间,如果是想要学习源码,最好的方式是有一个搭建好的调试环境,这里我已经搭建完成了,
clone之后install即可享用 - 如何在vscode直接调试react源码,对应到源码目录
- jsx在源码中的转换流程
✍️系列文章react实现原理系列
- 【react原理实践】使用babel手搓探索下jsx的原理
- 【喂饭式调试react源码】上手调试源码探究jsx原理
- 【上手调试源码系列】图解react几个核心包之间的关联
- 【上手调试源码系列】react启动流程,其实就是创建三大全局对象
🥝 一、简单介绍下react源码调试环境搭建的原理
1.调试源码的两种姿势
一般是有两种调试方式,这里我们主要介绍下第二种的原理
- 调试打包后的react
- 调试react源码,利用
Webpack Alias的原理
2.Webpack Alias 的原理
原理其实也很简单就是,webpack 的alias配置允许你定义一个别名,它是一个用于替代模块路径的简短字符串。当你在代码中导入一个模块时,如 import something from 'my-module/something',webpack 解析器会根据配置查找该模块,
- 如果匹配,webpack 就会将该路径替换成 alias 对应的路径,然后再继续正常的模块解析过程。
- 没有 alias 的情况下,它才会从
node_modules目录或者相对路径中寻找这个模块。
基于这个原理你可以将react的源码拉去到项目中你想要的位置,我搭建好的是放置在src/react下,然后yarn start将项目跑起来,去解决编译过程中产生的bug,最终搭建完成整个调试环境。
alias: {
// !!! 更改后的配置
react: path.join(paths.appSrc, 'react/packages/react'),
'react-dom': path.join(paths.appSrc, 'react/packages/react-dom'),
shared: path.join(paths.appSrc, 'react/packages/shared'),
'react-reconciler': path.join(paths.appSrc, 'react/packages/react-reconciler')
},
🍑 二、实操
1.在vscode进入调试流程
这里默认你已经clone项目了,项目里面已经配置好了vscode的调试文件,这里我们直接将项目跑起来yarn start
我们在app.js中打一个断点,行数左侧点一下,就有一个小红点。
我们切换到运行和调试,点击调试,进入vscode调试模式,代码会停止在我们打断点的地方
2.进入jsx转换流程
我们连续点击三次单步调试,注意看,我们这里是可以直接进入到react目录中的jsxWithValidation函数,很爽吧,如果你看过上一篇
文章的话,这个jsx校验函数的入参你会很眼熟。
进入到这里之后,我们折叠掉一些其他的校验代码,观察下这个函数,他的关键其实是jsxDev这个函数,入参也很眼熟吧。
command点击进入这个jsxDev函数,看到这个函数跟我们上一篇文章介绍的createElement处理逻辑是一致的,都是格式化数据符合ReactElement入参
我们command点击进入这个ReactElement函数,就是在构造ReactElement数据结构,可以打印看看,或者直接调试到这个位置,在vscode中查看,一个深度优先的生成顺序
我们再打印下app返回的ReactElement Tree
{
"type": "div",
"key": null,
"ref": null,
"props": {
"className": "App",
"children": {
"type": "header",
"key": null,
"ref": null,
"props": {
"className": "App-header",
"children": [
{
"type": "img",
"key": null,
"ref": null,
"props": {
"src": "/static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg",
"className": "App-logo",
"alt": "logo"
},
"_owner": null,
"_store": {}
},
{
"type": "p",
"key": null,
"ref": null,
"props": {
"children": [
"Edit ",
{
"type": "code",
"key": null,
"ref": null,
"props": {
"children": "src/App.js"
},
"_owner": null,
"_store": {}
},
" and save to reload."
]
},
"_owner": null,
"_store": {}
},
{
"type": "a",
"key": null,
"ref": null,
"props": {
"className": "App-link",
"href": "https://reactjs.org",
"target": "_blank",
"rel": "noopener noreferrer",
"children": "Learn React"
},
"_owner": null,
"_store": {}
}
]
},
"_owner": null,
"_store": {}
}
},
"_owner": null,
"_store": {}
}
这就是jsx整体在源码中的转换流程了。
🍎 推荐阅读
工程化系列
本系列是一个从0到1的实现过程,如果您有耐心跟着实现,您可以实现一个完整的react18 + ts5 + webpack5 + 代码质量&代码风格检测&自动修复 + storybook8 + rollup + git action实现的一个完整的组件库模板项目。如果您不打算自己配置,组件库仓库切换到rollup_comp分支即是完整的项目,当前实现已经足够个人使用,后续我们会新增webpack5优化、按需加载组件、实现一些常见的组件封装:包括但不限于拖拽排序、瀑布流、穿梭框、弹窗等
- 手把手带你搭建前端项目:react18、ts5、lint四剑客、webpack、storybook【保姆级教程一】
- 手把手带你搭建前端项目:react18、ts5、lint四剑客、webpack、storybook【保姆级教程二】
- 手把手带你搭建前端项目:react18、ts5、lint四剑客、webpack、storybook【保姆级教程三】
- 手把手带你搭建前端项目:react18、ts5、lint四剑客、webpack、storybook【保姆级教程四】
- 前端三大包管理器你知道多少?npm、yarn、pnpm
- 前端怎么可以不会GitHub Action一键部署?
面试手写系列
react实现原理系列
其他
🍋 写在最后
如果您看到这里了,并且觉得这篇文章对您有所帮助,希望您能够点赞👍和收藏⭐支持一下作者🙇🙇🙇,感谢🍺🍺!如果文中有任何不准确之处,也欢迎您指正,共同进步。感谢您的阅读,期待您的点赞👍和收藏⭐!
感兴趣的同学可以关注下我的公众号ObjectX前端实验室
🌟 少走弯路 | ObjectX前端实验室 🛠️「精选资源|实战经验|技术洞见」