前端那些事之源碼調試
小編從2017年入行,到現(xiàn)在已經六年的時間了,最開始會的東西也少,對于需求做起來都很費勁,而且那時候很多淺顯的東西,去網(wǎng)上一找一大片。隨著做的項目增加和突破了一個又一個的技術壁壘。小編也在成長,特別是最近小編遇到的一個性能問題,昨天晚上花了一晚上的時間,整理了一下自己針對element-ui源碼的調試過程,希望大家能一起進步。
主要是小編在使用element-ui做項目的時候,里面有個功能模塊,需要用的下拉樹,為了項目進度,小編就找了一個開源的el-select-tree。github地址:https://github.com/yujinpan/el-select-tree
當然,這個下拉樹的優(yōu)點在于可以支持element-ui中Select和Tree的全部的props、methods和events,這就讓我把這個融入到項目里很省心。根據(jù)官方的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官網(wǎng)】
<template><el-select-treewidth="120px"placeholder="請選擇內容"show-checkbox:data="treeData"v-model="value"filterablemultiple></el-select-tree></template><script>export defalut{name:'app',data(){return {value: [], // 因為組件中添加了multiple屬性,綁定的時候需要是數(shù)組,官網(wǎng)給的是int類型數(shù)據(jù),小編因為這個控制臺報錯還找了好久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>
當時,項目中的數(shù)據(jù)結構和和組件的結構不一樣,項目中的組件,需要用到props屬性對數(shù)據(jù)進行轉換,返回數(shù)據(jù)大概是這樣
{code:'000000',data:[{code:'1000000',name:'長春市',id:'a',children:[{code:'1000001',name:'南關區(qū)',id:'a1',},{code:'1000002',name:'朝陽區(qū)',id:'a2',},...]},{code:'2000000',name:'吉林市',id:'b',children:[{code:'2000001',name:'船營區(qū)',id:'b1',},{code:'2000002',name:'昌邑區(qū)',id:'b2',},...]},],msg:'數(shù)據(jù)加載成功'}
在element-ui中,Tree默認的props是這樣的

很顯然,后端返回的數(shù)據(jù)不符合默認格式,這個時候,我就在el-select-tree組件中添加了props,就變成了這樣
<template><el-select-treewidth="120px"placeholder="請選擇內容"show-checkbox:data="treeData"v-model="value"filterablemultiple:props="{label:(data) => {return data.code+'-'+data.name}, children:'children'}"></el-select-tree></template>
又這樣相安無事了一段時間,后來隨著數(shù)據(jù)的增加,返回到前端的數(shù)據(jù)數(shù)量和層級都越來越多,前端的壓力也越來越重,對于一些客戶端電腦性能不好的,經常能看到他們?yōu)g覽器【無響應】。作為前端,其實給出最好的建議就是懶加載,但是后端說這個接口是公共接口,不能輕易改動,卑微的小編只能默默的自己看看源碼,看看能不能從中間得到一些啟示
于是小編打開了node_modules下的elemen-ui/package/tree/src/node.js文件。其中這段代碼引起了小編的注意

這段代碼的意思就是將el-tree中的props循環(huán)一遍,我一想,那是不是tree上的props越少,在實例化Node的時候,性能開銷就不會那么大了呢?不管那么多,小編先將el-select-tree中的props去掉,然后通過js重新規(guī)范了一下數(shù)據(jù),將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", // 入口文件,相當整個包的入口,我們后續(xù)使用npm link創(chuàng)建鏈接的時候,需要改動內容"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": { // 開發(fā)依賴,每次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": "[email protected]","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命令的使用場景和實例
為依賴項創(chuàng)建全局軟鏈npm link。一個符號鏈接,簡稱軟鏈,是一個快捷方式,指向系統(tǒng)上的其它目錄或文件。
小編主要是從以下幾個步驟進行調試
1、復制node_modules下element-ui文件夾到桌面
2、進入~/Desktop/element-ui目錄下,執(zhí)行npm link命令
3、回到項目中,進入項目根目錄,執(zhí)行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即可
寫在最后
小編在找資料的時候,還發(fā)現(xiàn)了https://github.com/niesk/el-virtual-tree。據(jù)說可以通過虛擬滾動的方式解決tree的性能問題;
還發(fā)現(xiàn)了可以通過element-ui源碼,生成sourceMap的方式通過瀏覽器調試;
還發(fā)現(xiàn)了一個叫 patch-package 的包,據(jù)說可以緊急解決第三方庫的缺陷問題
還有文中說的懶加載處理Tree數(shù)據(jù),小編都將在后續(xù)的文章持續(xù)更新,希望大家持續(xù)關注,也可以推送給身邊的小伙伴!
