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一区二区
逼特逼视频在线| 99久久免费观看| 欧美日韩成人免费视频| 亚洲av综合色区| 国产经典久久久| 青青草原播放器| 国产女同无遮挡互慰高潮91| 中文字幕第21页| 杨幂毛片午夜性生毛片| 天天影视综合色| 天天操,天天操| 欧美成人乱码一二三四区免费| 男人操女人免费| 国内性生活视频| 黄色片久久久久| 在线观看免费视频高清游戏推荐| 99久久国产宗和精品1上映| 男女av免费观看| 久久婷婷综合色| www.偷拍.com| 久久艹国产精品| 激情婷婷综合网| 精品亚洲视频在线| 97超碰国产精品| 国产v亚洲v天堂无码久久久| 婷婷免费在线观看| 国产高清不卡无码视频| 日韩欧美一区二| 国产精品久久久毛片| 日本一区二区免费高清视频| 国产精品三级一区二区| 动漫av网站免费观看| 三区视频在线观看| 国产精品久久久久9999爆乳| 亚洲人成色77777| 欧美日韩亚洲国产成人| a级黄色一级片| 999在线观看| 国产精品12345| www.午夜色| 牛夜精品久久久久久久| 美女黄色免费看| 亚洲精品自拍网| 国产v片免费观看| 日韩视频在线观看一区二区三区| 精品久久久久久无码中文野结衣| 美女少妇一区二区| 超碰成人免费在线| 中文字幕第50页| 99re6在线观看| 国产精品无码av无码| 日韩国产小视频| 天堂网成人在线| 日韩大片一区二区| av动漫在线观看| 国产手机免费视频| 91免费版看片| 欧美精品色视频| 国产一级片中文字幕| 污视频免费在线观看网站| 黄色av网址在线播放| 日本免费a视频| 欧美大片免费播放| 三上悠亚免费在线观看| 182午夜视频| 992kp免费看片| 亚洲视频一二三四| 黄色一级片免费的| 中文字幕视频三区| 天天操精品视频| 免费看啪啪网站| mm131午夜| 国产情侣第一页| 亚洲 自拍 另类小说综合图区| 免费日韩在线观看| 男的插女的下面视频| 日韩欧美一区二| 欧美伦理片在线看| 免费成人黄色大片| 日本福利视频导航| av无码久久久久久不卡网站| 免费高清一区二区三区| 激情五月宗合网| 精品久久久久久久无码| 中文字幕有码av| 一道本视频在线观看| 青青草原国产免费| 2018国产在线| 日本特黄a级片| 久久久久福利视频| 波多野结衣乳巨码无在线| 99视频免费播放| 欧美少妇一级片| 男人操女人逼免费视频| av视屏在线播放| 天堂网成人在线| 日韩中文字幕在线视频观看| 国产精品后入内射日本在线观看| 波多野结衣天堂| 久久久久久av无码免费网站下载| av免费观看大全| 在线看的黄色网址| 17c丨国产丨精品视频| 国产野外作爱视频播放| 一级性生活视频| 色播五月激情五月| 无码人妻丰满熟妇区96| 两性午夜免费视频| 欧美性猛交久久久乱大交小说 | 鲁一鲁一鲁一鲁一澡| 欧美激情国内自拍| a在线视频观看| 中国老女人av| 91女神在线观看| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 香蕉视频xxxx| www.色偷偷.com| 亚洲中文字幕无码中文字| 2022中文字幕| 亚洲精品国产久| av中文字幕网址| 手机在线免费观看毛片| 国产男女免费视频| 日韩成人三级视频| 国产女主播av| av不卡在线免费观看| 污污的视频免费观看| jizzzz日本| 在线观看免费视频高清游戏推荐| 国产乱子伦农村叉叉叉| 777av视频| 国产免费一区二区视频| 黄网站色视频免费观看| 国产小视频免费| 久久观看最新视频| 黄色一级片国产| 亚洲爆乳无码精品aaa片蜜桃| 老司机av福利| 蜜桃网站在线观看| 女人色极品影院| 妺妺窝人体色777777| 啊啊啊一区二区| 国产又黄又猛视频| 色综合色综合色综合色综合| 香港日本韩国三级网站| 欧美黄色性生活| 青少年xxxxx性开放hg| 亚洲高清av一区二区三区| 国产精品一二三在线观看| 欧美 日韩 国产精品| 热99这里只有精品| av五月天在线| 中文字幕一区二区在线观看视频 | 欧日韩免费视频| 日韩欧美精品在线观看视频| 五月婷婷激情久久| 中文字幕55页| 18禁免费无码无遮挡不卡网站| 欧美aⅴ在线观看| 羞羞的视频在线| 大桥未久一区二区| 久在线观看视频| 日本黄色的视频| 日本福利视频在线观看| 色婷婷综合久久久久中文字幕 | 男人j进女人j| 虎白女粉嫩尤物福利视频| 在线能看的av网站| 成人精品视频在线播放| 国产三级国产精品国产专区50| 黄色a级三级三级三级| 国产午夜福利在线播放| 天堂av在线8| 成人免费视频91| 日本国产一级片| 国产视频一区二区三区在线播放| 中文字幕成人免费视频| 国产美女网站在线观看| 爱爱爱爱免费视频| 五月丁香综合缴情六月小说| 午夜av中文字幕| 老熟妇仑乱视频一区二区| 成人一级生活片| 日本高清xxxx| av中文字幕网址| 黄色一级二级三级| 人妻熟妇乱又伦精品视频| 超碰97免费观看| www.午夜av| 精产国品一二三区| 一本色道久久亚洲综合精品蜜桃 | 国产四区在线观看| 伊人网在线综合| www.99在线| 蜜臀视频一区二区三区| 黄色一级一级片| 国产综合免费视频| 国自产拍偷拍精品啪啪一区二区| 免费cad大片在线观看| 福利在线小视频|