Element UI 源码调试

504 阅读4分钟

前言

在使用Vue开发项目的过程中,Element UI 无疑是一个不错的组件库选择,一些场景下,当我们需要对Element UI源码进行调试时,应该怎么做呢?本文就该问题向大家进行简单的介绍。

安装 element ui 的库,并在入口引入:

Element UI 组件源码调试

安装及引入

首先创建一个Vue项目,并在项目的main.js中引入并使用Element UI

然后在 App.vue 中简单使用一下 button 组件

之后 npm run serve 把开发服务跑起来,就可以看到这样的页面:

Element UI 的组件正确的显示了。

接下来调试 button 组件的源码,也就是在这里出现了问题,我们应该在哪里打断点呢?

事件断点

我们可以知道,Element UI中这个 button 会处理点击事件,但是却不知道事件处理函数的代码在什么地方。

这种情况可以加一个事件断点:

在 sources 面板的 Event Listener Breakponts 里勾选 Mouse 的 click 事件,也就是在所有 click 事件的处理函数处断住。

然后再点击按钮可以发现,它在事件处理函数处断住了:

当已知组件处理了什么事件,但却不知道事件处理函数在哪的时候就可以用事件断点。

当然,这个事件处理函数并不是组件里的,因为 Vue 内部会先做一些处理,然后再交给组件处理。

所以,我们要先走到组件的事件处理函数:

单步执行、再进入函数内部,再单步执行、再进入函数内部,代码就会走到组件的事件处理函数:

methods、computed、props,这明显是源码里的了。但你再往上走两步,会发现又不是最初的源码:

template 变成了 render 函数,而且还有其他组件的代码,这明显是被编译打包之后的代码。

从文件名也可以看出来:

这是一个把所有组件代码编译后打包到一起的文件。

这样调试起来非常的不直观,有没有什么方法可以直接调试组件最初的源码呢?就是带 template 的单文件组件那种?

在这种情况下,这就要用到 sourcemap 了。

sourcemap

sourcemap 是在编译过程中产生的:

里面记录了目标代码和源代码的映射关系,调试的时候可以通过它映射回源码:

但是去 node_modules 下查看时,会发现没有这个文件的 sourcemap:

那该如何生成它的 sourcemap 呢?

这就要从源码重新编译了。

我们从 github 把它的源码下载下来:

git clone --depth=1 --single-branch git@github.com:ElemeFE/element.git

之后开始编译,在 npm scripts 中可以找到 dist 命令,这就是构建源码用的:

但是我们只需要 element-ui.common.js 这个文件:

其实只需要执行其中的一部分脚本,也就是这个:

所以在项目下执行 npx webpack --config build/webpack.common.js 即可:

然后在 lib 下就可以看到构建产物:

但我们的目标是生成带有 source-map 的代码,所以要改下配置:

修改 build/webpack.common.js,配置 devtool 为 cheap-module-source-map:

source-map 是生成 sourcemap 并关联,也就是这样:

module 是把中间 loader 产生的 sourcemap 也给合并到最终的 sourcemap 里,这样才能直接映射到源码。

cheap 是加快编译速度用的,只保留行的映射信息。

改完配置后再次 npx webpack --config build/webpack.common.js,就可以看到带有 sourcemap 的产物了:

把这俩文件复制到测试项目的 node_modules/element-ui 下覆盖下之前的:

devtool 设置为 source-map:

之后清掉 node_modules/.cache 下的缓存,重新跑 dev server:

这时会报错提示你 node 版本太低了,你需要再把 node 版本换回来:

跑起开发服务之后,再次用之前的方式调试 button 组件的源码:

你会发现现在的组件代码是带 template 语法的单文件组件的代码了!

这就是 sourcemap 的作用。

之后你会可以在这个组件里打断点然后调试。

有的同学可能会问,通过事件断点进入组件内部,这样有点麻烦,有没有更简单的方式?而且 button 组件有点击事件,但有的组件没有呀,这些组件该怎么调试呢?

确实,有了 sourcemap 之后就有更简单的调试方式了。

你可以在 sources 左边看到 ELEMENT 目录下有很多 vue 文件,这其实就是 Chrome DevTools 解析 sourcemap 之后列在这里的:

你可以直接在里面打断点调试。

比如我们加一个 tabs 组件:

把前面添加的那个事件断点去掉,在代码里手动打一个断点:

然后就可以通过源码调试 Element UI 组件了。

当然,有的组件找不到的时候,还是可以通过事件断点的方式来进入组件内部。

我们是通过 Chrome DevTools 调试的,其实用 VSCode Debugger 来调试它也是一样的,在 Chrome DevTools 里打的断点,在 VSCode Debugger 里同样会断住。

该文章借鉴了这位大佬的文章