前端那些事之源码调试
小编从2017年入行,到现在已经六年的时间了,最开始会的东西也少,对于需求做起来都很费劲,而且那时候很多浅显的东西,去网上一找一大片。随着做的项目增加和突破了一个又一个的技术壁垒。小编也在成长,特别是最近小编遇到的一个性能问题,昨天晚上花了一晚上的时间,整理了一下自己针对element-ui源码的调试过程,希望大家能一起进步。
主要是小编在使用element-ui做项目的时候,里面有个功能模块,需要用的下拉树,为了项目进度,小编就找了一个开源的el-select-tree。github地址:https://github.com/yujinpan/el-select-tree
当然,这个下拉树的优点在于可以支持element-ui中Select和Tree的全部的props、methods和events,这就让我把这个融入到项目里很省心。根据官方的demo,先写出了这样的代码
main.js【全局注册el-select-tree】
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import ElSelectTree from 'el-select-tree';
...
Vue.use(ElementUI);
Vue.use(ElSelectTree);
...
App.vue【使用el-select-tree组件。详细props可以参考element-ui官网】
<template>
<el-select-tree
width="120px"
placeholder="请选择内容"
show-checkbox
:data="treeData"
v-model="value"
filterable
multiple
></el-select-tree>
</template>
<script>
export defalut{
name:'app',
data(){
return {
value: [], // 因为组件中添加了multiple属性,绑定的时候需要是数组,官网给的是int类型数据,小编因为这个控制台报错还找了好久
treeData: [
{
value: 1,
label: 'text1',
children: [
{ value: 5, label: 'text5' },
{ value: 6, label: 'text6' }
]
},
{ value: 2, label: 'text2' },
{ value: 3, label: 'text3' },
{ value: 4, label: 'text5' }
]
}
}
}
</script>
当时,项目中的数据结构和和组件的结构不一样,项目中的组件,需要用到props属性对数据进行转换,返回数据大概是这样
{
code:'000000',
data:[
{
code:'1000000',
name:'长春市',
id:'a',
children:[
{
code:'1000001',
name:'南关区',
id:'a1',
},
{
code:'1000002',
name:'朝阳区',
id:'a2',
},
...
]
},
{
code:'2000000',
name:'吉林市',
id:'b',
children:[
{
code:'2000001',
name:'船营区',
id:'b1',
},
{
code:'2000002',
name:'昌邑区',
id:'b2',
},
...
]
},
],
msg:'数据加载成功'
}
在element-ui中,Tree默认的props是这样的
很显然,后端返回的数据不符合默认格式,这个时候,我就在el-select-tree组件中添加了props,就变成了这样
<template>
<el-select-tree
width="120px"
placeholder="请选择内容"
show-checkbox
:data="treeData"
v-model="value"
filterable
multiple
:props="{label:(data) => {return data.code+'-'+data.name}, children:'children'}"
></el-select-tree>
</template>
又这样相安无事了一段时间,后来随着数据的增加,返回到前端的数据数量和层级都越来越多,前端的压力也越来越重,对于一些客户端电脑性能不好的,经常能看到他们浏览器【无响应】。作为前端,其实给出最好的建议就是懒加载,但是后端说这个接口是公共接口,不能轻易改动,卑微的小编只能默默的自己看看源码,看看能不能从中间得到一些启示
于是小编打开了node_modules下的elemen-ui/package/tree/src/node.js文件。其中这段代码引起了小编的注意
这段代码的意思就是将el-tree中的props循环一遍,我一想,那是不是tree上的props越少,在实例化Node的时候,性能开销就不会那么大了呢?不管那么多,小编先将el-select-tree中的props去掉,然后通过js重新规范了一下数据,将code和name拼接后直接赋值给组件,刷新浏览器之后,小编感觉性能已经有了很大的提升。但是小编只是停留在猜测上,有没有什么办法能直接对node_modules中的代码进行调试呢?于是小编开始了对npm包中的内容展开了探索
说到这,小编先对项目内的package.json文件做个简单的说明
{
"name": "my-project", // 包名,唯一,在Vue项目入口文件的import Element from 'element-ui'就来自这
"version": "1.5.0", // 版本
"description": "Express server project using compression", // 描述
"main": "src/index.js", // 入口文件,相当整个包的入口,我们后续使用npm link创建链接的时候,需要改动内容
"scripts": { // 脚本文件,每次npm run <CMD> 就是在这里面
"start": "node index.js",
"dev": "nodemon",
"lint": "eslint **/*.js"
},
"dependencies": { // 依赖,每次npm install <packageName> --save 就会记录在这个位置
"express": "^4.16.4",
"compression": "~1.7.4"
},
"devDependencies": { // 开发依赖,每次npm install <packageName> --save-dev 就会记录在这个位置
"eslint": "^5.16.0",
"nodemon": "^1.18.11"
},
"repository": { // 代码仓库
"type": "git",
"url": "https://github.com/osiolabs/example.git"
},
"author": "Jon Church", // 作者
"contributors": [
{
"name": "Amber Matz",
"email": "example@example.com",
"url": "https://www.osiolabs.com/#team"
}
],
"keywords": [ // 关键字
"server",
"osiolabs",
"express",
"compression"
]
}
平时我们使用npm install <packageName>和 npm run <CMD>命令比较多。今天我们熟悉一下npm link命令。具体详情,可以参考 https://docs.npmjs.com/cli/v6/commands/npm-link/
在《前端架构师》一书中,已经介绍了npm link命令的使用场景和实例
为依赖项创建全局软链npm link。一个符号链接,简称软链,是一个快捷方式,指向系统上的其它目录或文件。
小编主要是从以下几个步骤进行调试
1、复制node_modules下element-ui文件夹到桌面
2、进入~/Desktop/element-ui目录下,执行npm link命令
3、回到项目中,进入项目根目录,执行npm link element-ui
这个时候,在~/Desktop/element-ui/package中打断点的时候,并不会有效果,查看了一下~/Desktop/element-ui/package.json文件中的main,指向的并不是~/Desktop/element-ui/package/index.js文件,这个时候,我们修改一下~/Desktop/element-ui/package.json中入口文件地址即可
4、这个时候我们可以debugger,或者console,都很方便,能让我们更深层次的理解源码和对第三方库的使用。
5、我们需要断开链接的时候,使用npm unlink即可
写在最后
小编在找资料的时候,还发现了https://github.com/niesk/el-virtual-tree。据说可以通过虚拟滚动的方式解决tree的性能问题;
还发现了可以通过element-ui源码,生成sourceMap的方式通过浏览器调试;
还发现了一个叫 patch-package 的包,据说可以紧急解决第三方库的缺陷问题
还有文中说的懒加载处理Tree数据,小编都将在后续的文章持续更新,希望大家持续关注,也可以推送给身边的小伙伴!