gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

工具分享:實現(xiàn)前端埋點的自動化管理

工具分享:實現(xiàn)前端埋點的自動化管理

前端(vue)入門到精通課程,老師在線輔導(dǎo):聯(lián)系老師
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點擊使用

埋點一直是 H5 項目中的重要一環(huán),埋點數(shù)據(jù)更是后期改善業(yè)務(wù)和技術(shù)優(yōu)化的重要基礎(chǔ)。【推薦學(xué)習(xí):web前端、編程教學(xué)】

在日常的工作中,經(jīng)常會有產(chǎn)品或者業(yè)務(wù)的同學(xué)來問,“這個項目現(xiàn)在有哪些埋點?”,“這個埋點用在哪些地方?”像這樣的問題基本上都是問一次查一次代碼,效率很低。

工具分享:實現(xiàn)前端埋點的自動化管理

這也許跟埋點本身的性質(zhì)有關(guān)系。埋點屬于相對獨立的功能,隨著迭代的進行,開發(fā)者很難記住埋點的用途。開發(fā)者出于自測驗證的需要,也得對項目中的埋點數(shù)據(jù)加以整理。因此結(jié)合當(dāng)前的場景,可以實現(xiàn)一個工具:通過對代碼進行掃描,分析埋點相關(guān)的代碼,并對之加以處理,轉(zhuǎn)化成特定的數(shù)據(jù),供后續(xù)在其他的管理平臺中使用。

實現(xiàn)思路

這個工具大致可以分成三個部分,JSDoc 提取埋點、路由依賴分析和 ESLint 插件。

  • JSDoc 是根據(jù) JavaScript 中的注釋信息,生成 API 文檔的一個工具。結(jié)合 JSDoc 的這一個特性,這個埋點工具把 JSDoc 作為核心部分,用于輸出代碼中的埋點數(shù)據(jù)。
  • Webpack 插件作為輔助,為 JSDoc 提供路由信息。
  • ESLint 插件則作為最后的檢驗,確保文件中的埋點代碼都有對應(yīng)的 JSDoc 注釋。

工具分享:實現(xiàn)前端埋點的自動化管理

自定義 JSDoc 標(biāo)記埋點

我們知道,JSDoc 可以根據(jù)代碼中的注釋輸出一份文檔。首先我們自定義一個 JSDoc 的 tag 來標(biāo)注這是一個埋點的注釋,這樣后續(xù)處理時可以過濾掉其他注釋的干擾。結(jié)合具體項目中使用的代碼可以畫出這樣一個流程圖:

工具分享:實現(xiàn)前端埋點的自動化管理

下面是具體的代碼實現(xiàn)的過程。

編寫 JSDoc 插件,自定義一個 tag:

// jsdoc.plugin.js // 自定義一個 @log,含有 @log 才是埋點的注釋 exports.defineTags = function (dictionary) {   dictionary.defineTag('log', {     canHaveName: true,     onTagged: function (doclet, tag) {       doclet.meta.log = tag.text;     },   }); };
登錄后復(fù)制

解析 .ts 和 .vue 文件。

// jsdoc.plugin.js exports.handlers = {   beforeParse: function (e) {     // 對文件預(yù)處理     if (/.vue/.test(e.filename)) {       // 解析 vue 文件       const component = compiler.parseComponent(e.source);       // 獲取 vue 文件的 script 代碼       const ast = parse.parse(component.script.content, {         // ...       });     }      if (/.ts/.test(e.filename)) {       // ts 轉(zhuǎn) js     }   }, };
登錄后復(fù)制

自定義 JSDoc 模版。

// publish.js exports.publish = function (taffyData, opts, tutorials) {   // ...   data().each(function (doclet) {     // 有 log 這個 tag 的才是埋點注釋     if (doclet.meta && doclet.meta.log) {       doclet.tags?.forEach((item) => {         // 獲取對應(yīng)的路由地址       });        // 拿到埋點數(shù)據(jù)       logData.push({});     }   });    // 輸出 md 文檔   fs.writeFileSync(outpath, mdContent, 'utf8'); };
登錄后復(fù)制

到這里,已經(jīng)可以完整地輸出代碼中的所有埋點了。此時再來看下目前這個工具的能力:

  • 自動提取埋點信息,生成埋點文檔:✅
  • 自動給埋點注釋添加自定義 tag(@log):❌
  • 自動給埋點注釋添加上報的埋點信息:❌
  • 自動給埋點注釋添加路由信息:❌
  • 自動給埋點注釋添加埋點描述信息:❌
  • 自動提示沒有注釋的埋點代碼:❌

通過上面的梳理我們可以看出:

  • 需要手動給每個埋點加上注釋
  • 需要手動去查每個埋點所對應(yīng)的路由
  • 如果忘了給埋點加注釋怎么辦?

做這個工具的初衷,就是為省去一些重復(fù)繁瑣的工作,如果為了能自動從代碼中輸入一份文檔而增加了其他一些工作量,這未免有點得不償失。通過對這些問題的分析,可以得出以下的解決方案:

  • 需要手動給每個埋點加上注釋 -> 自動填充代碼 -> ESLint fix 功能 / VSCode 插件
  • 需要手動去查每個埋點所對應(yīng)的路由 -> 自動找到組件所對應(yīng)的路由 -> Webpack 依賴分析
  • 如果忘了給埋點加注釋怎么辦?-> 忘寫注釋有提示 -> ESLint 插件

到這一步解決問題的方法就已經(jīng)變得明朗了。接下來讓看一下 webpack 插件與 ESLint 插件的實現(xiàn)過程。

路由依賴分析

webpack 本身自帶依賴分析,輕松就能拿到組件間的父子關(guān)系。

compiler.hooks.normalModuleFactory.tap('routeAnalysePlugin', (nmf) => {   nmf.hooks.afterResolve.tapAsync('routeAnalysePlugin', (result, callback) => {     const { resourceResolveData } = result;     // 子組件     const path = resourceResolveData.path;      // 父組件     const fatherPath = resourceResolveData.context.issuer;      // 只獲取 vue 文件的依賴關(guān)系     if (/.vue/.test(path) && /.vue/.test(fatherPath)) {       // 將組件間的父子關(guān)系存到變量中     }   }); });
登錄后復(fù)制

把組件之間的依賴關(guān)系拼成我們想要的數(shù)據(jù)格式

[   {     "path": "src/views/register-v2/index.vue",     "deps": [       {         "path": "src/components/landing-banner/index.vue",         "deps": []       }     ]   }   // ... ]
登錄后復(fù)制

組件之間的依賴關(guān)系有了,接下來就是找到組件和路由的對應(yīng)關(guān)系,這里我們用 AST 來解析路由文件,獲取路由和組件的對應(yīng)關(guān)系。

// 遍歷路由文件 for (let i = 0; i < this.routePaths.length; i++) {   // ...   traverse(ast, {     enter(path) {       // 找出組件和路由的對應(yīng)關(guān)系       path.node.properties.forEach((item) => {         // 組件         if (item.key.name === 'component') {         }          // 路由地址         if (item.key.name === 'path') {         }       });     },   }); }
登錄后復(fù)制

同樣地,把組件與路由的映射關(guān)系拼成合適的數(shù)據(jù)格式。

{   "src/views/register-v3/index.vue": "/register"   // ... }
登錄后復(fù)制

再將路由的映射關(guān)系和組件間的依賴關(guān)系整合到一起,得出每個組件與路由的對應(yīng)關(guān)系。

{   "src/components/landing-banner/index.vue": [     "/register_v2",     "/register"     //...   ]   // ... }
登錄后復(fù)制

因為使用 AST 遍歷的方式來解析路由文件,目前支持的解析的路由文件寫法有以下四種,基本上滿足了當(dāng)前的場景:

const page1 = (resolve) => {   require.ensure(     [],     () => {       resolve(require('page1.vue'));     },     'page1',   ); };  const page2 = () =>   import(     /* webpackChunkName: "page2" */     'page2.vue'   );  export default [   { path: '/page1', component: page1 },   { path: '/page2', component: page2 },   {     path: '/page3',     component: (resolve) => {       require.ensure(         [],         () => {           resolve(require('page3.vue'));         },         'page3',       );     },   },    {     path: '/page4',     component: () =>       import(         /* webpackChunkName: "page4" */         'page4.vue'       ),   }, ];
登錄后復(fù)制

再得到了上面的對應(yīng)關(guān)系之后,可以把埋點數(shù)據(jù)放到傳到埋點管理平臺上,從而實現(xiàn)一鍵查詢:

工具分享:實現(xiàn)前端埋點的自動化管理

編寫 ESLint 插件

先來看看代碼中埋點上報的三種方式:

// 神策 sdk sensors.track('xxx', {});  // 掛載到 Vue 實例中 this.$sa.track('xxx', {});  // 裝飾器 @SensorTrack('xxx', {})
登錄后復(fù)制

觀察上面三種方式,可以知道埋點上報是通過 track 函數(shù)和 SensorTrack 函數(shù),所以我們的 ESLint 插件對這兩個函數(shù)進行校驗。

function create(context) {   // 調(diào)用 track 函數(shù)的對象   const checkList = ['sensor', 'sensors', '$sa', 'sa'];    return {     Literal: function (node) {       // ...       // 調(diào)用埋點函數(shù)而缺少注釋時       if (         isNoComment &&         ((isTrack && isSensor) || (is$Track && isThisExpression))       ) {         context.report({           node,           messageId: 'missingComment',           fix: function (fixer) {             // 自動修復(fù)           },         });       }        // 使用修飾器但沒有注釋時       if (         callee.name === 'SensorTrack' &&         sourceCode.getCommentsBefore(node).length === 0       ) {         context.report({           node,           messageId: 'missingComment',           fix: function (fixer) {             // 自動修復(fù)           },         });       }     },   }; }
登錄后復(fù)制

看下完成后的效果:

工具分享:實現(xiàn)前端埋點的自動化管理

效果對比

我們再來對比下優(yōu)化前后的區(qū)別:

優(yōu)化前 優(yōu)化后
自動提取埋點信息,生成埋點文檔
自動給埋點注釋添加自定義 tag(@log)
自動給埋點注釋添加上報的埋點信息
自動給埋點注釋添加路由信息
自動給埋點注釋添加埋點描述信息
自動提示沒有注釋的埋點代碼

優(yōu)化之后除了整個流程基本都由工具自動完成,剩下一個埋點描述信息。因為埋點的描述信息只是為了讓我們更好地理解這個埋點,本身并不在上報的代碼中,所以工具沒有辦法自動生成,但是我們可以直接在產(chǎn)品提供的埋點文檔中拷貝過來完成這一步。

總結(jié)

在項目中接入這個工具之后,可以快速地知道項目的埋點有哪些以及各個埋點所在的頁面,也方便我們對埋點的梳理,同時利用導(dǎo)出的埋點數(shù)據(jù)開發(fā)后臺應(yīng)用,有效地提升了開發(fā)者效率。

這個工具的實現(xiàn)是在 JSDoc、webpack 和 ESLint 插件的加持下水到渠成的,說是水到渠成是因為一開始的想法只是做到第一步,先有個一鍵查詢功能和能夠輸出一份文檔用著先。但是第一版出來后發(fā)現(xiàn)要手動去處理這些埋點注釋還是比較繁瑣,恰巧平常開發(fā)中常見的 webpack 插件和 ESLint 插件可以很好地解決這些問題,于是便有路由依賴分析和 ESLint 插件。像是《牧羊少年奇幻之旅》中所說的,“如果你下定決心要做一件事情,整個宇宙都會合力幫助你。”

【推薦學(xué)習(xí):web前端開發(fā)、編程基礎(chǔ)視頻教程】

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
激情深爱综合网| 久久国产成人精品国产成人亚洲 | 欧美精品色婷婷五月综合| 日韩欧美精品在线观看视频| 亚洲 欧美 综合 另类 中字| 黄色三级中文字幕| 青娱乐精品在线| 三上悠亚av一区二区三区| 国产成人精品无码播放| 无码人妻h动漫| 超碰在线97免费| 欧美成人福利在线观看| 一路向西2在线观看| 91亚洲精品久久久蜜桃借种| 岛国av在线免费| 在线观看视频在线观看| 永久免费看av| 免费看国产一级片| 精品国产成人av在线免| 天天操天天爽天天射| 久久久久久久久久一区| 欧美aaa在线观看| 亚洲精品久久久久久久蜜桃臀| 六月婷婷在线视频| 亚洲性生活网站| 懂色av粉嫩av蜜臀av| 韩日视频在线观看| www.色就是色| 久久最新免费视频| 日韩欧美国产免费| 欧美日韩久久婷婷| 黄色片网址在线观看| 亚洲xxx在线观看| 毛片av在线播放| 九九热精品在线播放| 国产精品av免费观看| 爱情岛论坛成人| 欧美 国产 精品| 向日葵污视频在线观看| 99er在线视频| 蜜臀一区二区三区精品免费视频| 欧美 亚洲 视频| 美女一区二区三区视频| 日韩在线视频在线| 中文字幕永久有效| 亚洲人成无码www久久久| 成人一区二区av| 色撸撸在线观看| 15—17女人毛片| 久久成人免费观看| 成人在线观看毛片| 秋霞在线一区二区| 美女少妇一区二区| 激情综合网俺也去| 日韩欧美一区二| 女人帮男人橹视频播放| 亚洲精品mv在线观看| 免费看污污网站| 手机看片福利盒子久久| 久久久亚洲精品无码| 今天免费高清在线观看国语| 国产福利精品一区二区三区| 国产天堂在线播放| 男人插女人下面免费视频| 精品少妇人妻av免费久久洗澡| 久久久九九九热| 国内自拍第二页| 欧美视频亚洲图片| 亚洲欧美天堂在线| 日韩欧美亚洲另类| 午夜不卡福利视频| 8x8x华人在线| 真人抽搐一进一出视频| 免费在线黄网站| 国产精品久久中文字幕| 波多野结衣家庭教师在线| 日日碰狠狠添天天爽超碰97| 蜜桃传媒一区二区三区| 四虎永久在线精品无码视频| 日韩久久一级片| 国产精品视频黄色| 亚洲污视频在线观看| 亚洲图片 自拍偷拍| 黄色录像特级片| 黄色大片中文字幕| 无码人妻丰满熟妇区毛片| 国产一级不卡毛片| 国内av免费观看| 黄色www网站| 精品999在线| 精品国产三级a∨在线| 大西瓜av在线| 丰满少妇在线观看| 善良的小姨在线| 国产亚洲精品网站| 一级黄色特级片| a级黄色片免费| 免费在线观看的毛片| 久久精品一卡二卡| 男人操女人逼免费视频| 在线黄色免费观看| 日韩精品视频在线观看视频 | 美女黄色片视频| 午夜免费视频网站| 成年人黄色片视频| 成人一区二区av| 欧美三级午夜理伦三级富婆| 真人做人试看60分钟免费| 麻豆av免费在线| 国产毛片久久久久久国产毛片| 国产男女激情视频| 91xxx视频| 久热精品在线播放| 蜜桃传媒一区二区三区| 国产精品久久久久久久99| 欧美成人免费在线观看视频| 污视频网站观看| 亚洲综合在线网站| avav在线看| 欧美色图色综合| 黄色影视在线观看| 欧洲在线免费视频| 看看黄色一级片| 日本人视频jizz页码69| 欧美精品第三页| 爱福利视频一区二区| 欧美日韩不卡在线视频| 特级西西444| 男人的天堂视频在线| xxx中文字幕| 黄色一级视频播放| 久久精品一卡二卡| 国产卡一卡二在线| 欧美午夜精品理论片| 少妇一级淫免费播放| 亚洲天堂国产视频| 在线观看岛国av| 日本高清免费观看| 日本道在线视频| 国产精品国三级国产av| 大胆欧美熟妇xx| 日韩av综合在线观看| 青青青免费在线| 精品久久久久av| 亚洲36d大奶网| 99亚洲精品视频| www.xxx麻豆| 女人天堂av手机在线| 男人天堂1024| 在线观看免费的av| 国产又粗又长又爽视频| www.射射射| 一区二区三区韩国| 在线观看成人免费| 日本日本19xxxⅹhd乱影响| 爱情岛论坛vip永久入口| 在线看免费毛片| 欧美精品久久久久久久免费| 无码人妻精品一区二区三区66| 欧美日韩中文不卡| 欧美高清中文字幕| 精品一卡二卡三卡| 国产精品999.| 精品国产一区三区| 亚洲国产午夜精品| 国产深夜男女无套内射| 网站一区二区三区| 久久av综合网| 亚洲一区二区福利视频| 欧美一区二区激情| 手机av在线网站| 免费激情视频在线观看| 午夜av中文字幕| 日韩精品一区二区三区色欲av| 日韩欧美亚洲另类| 黑森林福利视频导航| 婷婷视频在线播放| 国产极品美女高潮无套久久久| 亚欧精品在线视频| 亚洲国产精品三区| 日韩在线综合网| 国产成人永久免费视频| 嫩草视频免费在线观看| 国产第一页视频| 成人免费a级片| 加勒比海盗1在线观看免费国语版| 成人黄色片视频| 黄色网页免费在线观看| 国产乱人伦精品一区二区三区| 青青草原国产在线视频| 密臀av一区二区三区| 免费黄色福利视频| 国模无码视频一区二区三区| 欧美黄网在线观看| 精品久久久无码人妻字幂| 午夜在线视频免费观看| 国产91av视频在线观看| 99日在线视频| 国产a级片免费看| 国产四区在线观看|