click-to-component源码阅读

click-to-component 是一个react组件,接入后可以实现一键跳转到源码,很大程度提升了开发效率。这里我尝试阅读源码,并记录一些关键点。

源码结构

项目整体使用了pnpm作为包管理工具,使用pnpm workspace管理多个包。

其中packages下的click-to-component-react是核心包,而apps下的是接入该组件包的项目,用于测试验证。

1
2
3
4
5
6
7
8
9
10
├── apps
│   ├── cra
│   ├── next
│   └── remix
├── package.json
├── packages
│   └── click-to-react-component
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
└── turbo.json

源码阅读

源码上从index入口开始解读。

1
2
export const ClickToComponent =
process.env.NODE_ENV === 'development' ? Component : () => null

这里使用NODE_ENV来判断是否是开发环境,如果是开发环境,则返回Component组件,否则返回一个空组件。这样做的好处是生产打包状态下,这个组件不会被引入,从而减少打包体积。

在整个组件加载时,window直接监听了click/contextmenu/keydown/keyup/mousemove/blur事件。当点击时,事件可以获取到目标element元素。

开发状态下,元素的属性中是有__reactInternalInstance$或者__reactFiber开头的属性。这个属性指向的就是fiber对象。

fiber对象中有_debugOwner属性,这个属性指向的就是fiber对象的父级fiber对象。即当使用下面逻辑可以获得层层嵌套的fiber对象直到根fiber对象。

1
2
3
4
5
6
7
8
const instances = new Set()
let instance = getReactInstanceForElement(element)

while (instance) {
instances.add(instance)

instance = instance._debugOwner
}

同时fiber对象中有_debugSource属性,这个属性指向的就是源码文件。

1
2
3
4
5
const {
columnNumber = 1,
fileName,
lineNumber = 1,
} = instance._debugSource

注意:生产打包元素身上也是有fiber属性,但没有debug调试属性信息

当知道了源码文件路径,行列号,只需要搭配URL Scheme就可以跳转到对应的源码文件。vscode有很好的URL Scheme,可以参考vscode的URL Scheme

写在最后

到此就完成了整个组件的源码阅读,整个组件的实现逻辑并不复杂。但也考察了基础的知识。

  1. react fiber
  2. tree shaking
  3. 事件监听
  4. URL Scheme