当前位置: 首页 > 科技观察

我是如何调试ElementUI源码的

时间:2023-03-17 15:05:18 科技观察

上一篇文章写了如何调试antd的源码,反响很好:但是很多写Vue的朋友,平时可能用到ElementUI的组件库,所以这篇文章就讲讲如何调试ElementUI的源码。首先,我们使用VueCLI创建一个vue2项目:yarnglobaladd@vue/clivuecreateelement-vue-test创建成功后,进入项目目录安装elementui的库,在入口处导入:然后在App.vue使用按钮组件后,运行yarnrunserve运行开发服务,可以看到这样一个页面:ElementUI的组件都正确显示了。接下来调试按钮组件的源码,那么问题来了,我怎么知道断点在哪里呢?我们能知道的是这个按钮会处理点击事件,但是我们不知道事件处理程序的代码在哪里。这种情况下,可以添加事件断点:在sources面板的EventListenerBreakpons中勾选Mouse的点击事件,即停在所有点击事件的处理函数处。然后你点击按钮再试一次:你会发现它在事件处理程序处坏了。当您知道组件处理什么事件,但不知道事件处理程序在哪里时,您可以使用事件断点。当然,这个事件处理器是不在组件中的,因为Vue内部会做一些处理,然后交给组件处理。所以,我们要先去组件的事件处理函数:单步执行,然后进入函数,然后单步执行,再进入函数,代码会去组件的事件处理函数:methods,computed,props,this很明显是在源码里。但是往上走两步,你会发现不是原来的源码:模板变成了render函数,还有其他组件的代码,很明显是编译打包的代码。从文件名也可以看出:这是一个将所有组件代码编译并打包在一起的文件。这样虽然可以调试,但是一定很不爽。能直接调试组件的原始源码吗?是那种带模板的单文件组件吗?是的,必须使用sourcemap。sourcemap是在编译过程中生成的:它记录了目标代码和源代码之间的映射关系,调试时可以用来映射回源代码:但是如果你去node_modules,你会发现有此文件没有源映射:如何生成它的源映射呢?这需要从源代码重新编译。我们从github上下载了它的源码:gitclone--depth=1--single-branchgit@github.com:ElemeFE/element.git--depth=1是只下载一个commit,--single-branch是下载单个分支,使下载速度可以快几十倍,是一种加速技巧。进入element目录,安装依赖,你会遇到一个经常出现的前端头疼问题,node-sass安装报错:解决这个问题的方法是将node版本切换到node-sass版本对应的版本。在package.json中可以看到node-sass是4.11.0。打开node-sass的github主页:会看到这样一张版本对应表:4.11对应node11,那么把node切换到11就可以了,然后再次yarninstalldependencies就可以成功了。然后开始编译,在npmscripts中可以找到dist命令,它是用来构建源码的:但我们只需要element-ui.common.js文件:其实只需要执行部分脚本,就是这样的:所以在项目中执行npxwebpack--configbuild/webpack.common.js:然后就可以看到lib:下的buildproduct但是我们的目标是用source-map生成代码,所以需要改配置:修改build/webpack.common.js,配置devtool为cheap-module-source-map:source-map是生成并关联sourcemap,即module是将中间加载器生成的sourcemap合并到最终的sourcemap,让Map直接到源码。cheap用于加速编译,只保留行的映射信息。更改配置后,再次运行yarnrundist,可以看到带有sourcemap的产品:将这两个文件复制到测试项目的node_modules/element-ui中并覆盖之前的:然后清除node_modules/.cache下的缓存,重新运行devserver:此时会报错提示node版本过低,需要将node版本改回来:运行开发服务后,debug源码按钮组件再按之前的方式:会发现当前组件的代码是模板语法的单文件组件的代码!这就是sourcemaps所做的。然后您将能够在此组件中设置断点并进行调试。可能有同学会问,通过事件断点进入组件有点麻烦,有没有更简单的方法?而且按钮组件有点击事件,有的组件没有。如何调试这些组件?确实,使用sourcemap,有一种更简单的调试方法。在sources的左侧可以看到ELEMENT目录下有很多vue文件,ChromeDevTools解析sourcemap后,其实是在这里列出来的:可以直接在里面断点调试。比如我们添加一个tabs组件:去掉之前添加的事件断点,在代码中手动设置断点:那么你会发现可以调试ElementUI组件的源码了!当然,当有些组件找不到时,仍然可以通过事件断点进入组件内部。我们通过ChromeDevTools对其进行调试。其实用VSCodeDebugger来调试也是一样的。在ChromeDevTools中设置的断点也将在VSCode调试器中被破坏。小结今天我们调试了ElementUI的源码。定位组件的代码是通过事件断点,因为我们知道它触发了什么事件,但是我们不知道事件处理程序在哪里。但是组件代码是编译打包的,并不是原来的源代码。为了调试原来的源码,我们下载了ElementUI的代码,用sourcemap构建了一个代码。覆盖项目node_modules下的代码,再次运行devserver,就可以直接调试组件的源码了。有了sourcemap,ChromeDevTools会直接列出sources中的vue文件,我们可以找到对应的vue文件断点,就不需要通过事件断点来找了。能够调试ElementUI的源码后,如果想知道组件内部是什么逻辑,可以直接在源码断点调试,很香。