目錄
實作想法
自訂JSDoc 標記埋點
路由依賴分析
编写 ESLint 插件
效果对比
总结
首頁 web前端 前端問答 工具分享:實現前端埋點的自動化管理

工具分享:實現前端埋點的自動化管理

Dec 07, 2022 pm 04:14 PM
web前端 webpack 前端 vue.js 前端埋點 eslint

工具分享:實現前端埋點的自動化管理

埋藏點一直是 H5 專案中的重要一環,埋點資料更是後期改善業務和技術最佳化的重要基礎。 【推薦學習:web前端程式設計教學

在日常的工作中,常常會有產品或是業務的同學來問,「這個專案現在有哪些埋點?」,「這個埋點用在哪些地方?」像這樣的問題基本上都是問一次查一次程式碼,效率很低。

這也許跟埋點本身的性質有關係。埋點屬於相對獨立的功能,隨著迭代的進行,開發者很難記住埋點的用途。開發者出於自測驗證的需要,也得對專案中的埋設資料加以整理。因此結合當前的場景,可以實現一個工具:透過對程式碼進行掃描,分析埋點相關的程式碼,並對之加以處理,轉化成特定的數據,供後續在其他的管理平台中使用。

實作想法

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

  • JSDoc 是根據 JavaScript 中的註解訊息,產生 API 文件的工具。結合 JSDoc 的這個特性,這個埋點工具把 JSDoc 作為核心部分,用於輸出程式碼中的埋點資料。
  • Webpack 外掛程式作為輔助,為 JSDoc 提供路由資訊。
  • ESLint 外掛則作為最後的檢驗,確保檔案中的埋點程式碼都有對應的 JSDoc 註解。

自訂JSDoc 標記埋點

我們知道,JSDoc 可以根據程式碼中的註解輸出一份文檔。首先我們自訂一個 JSDoc 的 tag 來標註這是一個埋點的註釋,這樣後續處理時可以過濾掉其他註釋的干擾。結合具體專案中使用的程式碼可以畫出這樣一個流程圖:

下面是具體的程式碼實現的過程。

寫 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;
    },
  });
};
登入後複製

解析 .ts 和 .vue 檔案。

// jsdoc.plugin.js
exports.handlers = {
  beforeParse: function (e) {
    // 对文件预处理
    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 转 js
    }
  },
};
登入後複製

自訂 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) => {
        // 获取对应的路由地址
      });

      // 拿到埋点数据
      logData.push({});
    }
  });

  // 输出 md 文档
  fs.writeFileSync(outpath, mdContent, 'utf8');
};
登入後複製

到這裡,已經可以完整地輸出程式碼中的所有埋點了。此時再來看下目前這個工具的能力:

  • 自動提取埋點信息,生成埋點文檔:✅
  • 自動給埋點註釋添加自定義tag(@log ):❌
  • 自動為埋點註解新增上報的埋點資訊:❌
  • 自動新增路由資訊:❌
  • 自動給埋點註解新增埋點描述資訊:❌
  • 自動提示沒有註解的埋點程式碼:❌

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

  • 需要手動為每個埋點加上註解
  • 需要手動去查每個埋點所對應的路由
  • 如果忘了給埋點加註解怎麼辦?

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

  • 需要手動為每個埋點加上註解-> 自動填入程式碼-> ESLint fix 功能/ VSCode 外掛程式
  • 需要手動去查每個埋點所對應的路由-> 自動找到元件所對應的路由-> Webpack 依賴分析
  • 如果忘了給埋點加上註解怎麼辦? -> 忘寫註解有提示 -> ESLint 外掛

到這一步解決問題的方法就已經變得明朗了。接下來讓來看看 webpack 外掛程式與 ESLint 外掛程式的實作過程。

路由依賴分析

webpack 本身自帶依賴分析,輕鬆就能拿到元件間的父子關係。

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 文件的依赖关系
    if (/.vue/.test(path) && /.vue/.test(fatherPath)) {
      // 将组件间的父子关系存到变量中
    }
  });
});
登入後複製

把元件之間的依賴關係拼成我們想要的資料格式

[
  {
    "path": "src/views/register-v2/index.vue",
    "deps": [
      {
        "path": "src/components/landing-banner/index.vue",
        "deps": []
      }
    ]
  }
  // ...
]
登入後複製

组件之间的依赖关系有了,接下来就是找到组件和路由的对应关系,这里我们用 AST 来解析路由文件,获取路由和组件的对应关系。

// 遍历路由文件
for (let i = 0; i < this.routePaths.length; i++) {
  // ...
  traverse(ast, {
    enter(path) {
      // 找出组件和路由的对应关系
      path.node.properties.forEach((item) => {
        // 组件
        if (item.key.name === &#39;component&#39;) {
        }

        // 路由地址
        if (item.key.name === &#39;path&#39;) {
        }
      });
    },
  });
}
登入後複製

同样地,把组件与路由的映射关系拼成合适的数据格式。

{
  "src/views/register-v3/index.vue": "/register"
  // ...
}
登入後複製

再将路由的映射关系和组件间的依赖关系整合到一起,得出每个组件与路由的对应关系。

{
  "src/components/landing-banner/index.vue": [
    "/register_v2",
    "/register"
    //...
  ]
  // ...
}
登入後複製

因为使用 AST 遍历的方式来解析路由文件,目前支持的解析的路由文件写法有以下四种,基本上满足了当前的场景:

const page1 = (resolve) => {
  require.ensure(
    [],
    () => {
      resolve(require(&#39;page1.vue&#39;));
    },
    &#39;page1&#39;,
  );
};

const page2 = () =>
  import(
    /* webpackChunkName: "page2" */
    &#39;page2.vue&#39;
  );

export default [
  { path: &#39;/page1&#39;, component: page1 },
  { path: &#39;/page2&#39;, component: page2 },
  {
    path: &#39;/page3&#39;,
    component: (resolve) => {
      require.ensure(
        [],
        () => {
          resolve(require(&#39;page3.vue&#39;));
        },
        &#39;page3&#39;,
      );
    },
  },

  {
    path: &#39;/page4&#39;,
    component: () =>
      import(
        /* webpackChunkName: "page4" */
        &#39;page4.vue&#39;
      ),
  },
];
登入後複製

再得到了上面的对应关系之后,可以把埋点数据放到传到埋点管理平台上,从而实现一键查询:

编写 ESLint 插件

先来看看代码中埋点上报的三种方式:

// 神策 sdk
sensors.track(&#39;xxx&#39;, {});

// 挂载到 Vue 实例中
this.$sa.track(&#39;xxx&#39;, {});

// 装饰器
@SensorTrack(&#39;xxx&#39;, {})
登入後複製

观察上面三种方式,可以知道埋点上报是通过 track 函数和 SensorTrack 函数,所以我们的 ESLint 插件对这两个函数进行校验。

function create(context) {
  // 调用 track 函数的对象
  const checkList = [&#39;sensor&#39;, &#39;sensors&#39;, &#39;$sa&#39;, &#39;sa&#39;];

  return {
    Literal: function (node) {
      // ...
      // 调用埋点函数而缺少注释时
      if (
        isNoComment &&
        ((isTrack && isSensor) || (is$Track && isThisExpression))
      ) {
        context.report({
          node,
          messageId: &#39;missingComment&#39;,
          fix: function (fixer) {
            // 自动修复
          },
        });
      }

      // 使用修饰器但没有注释时
      if (
        callee.name === &#39;SensorTrack&#39; &&
        sourceCode.getCommentsBefore(node).length === 0
      ) {
        context.report({
          node,
          messageId: &#39;missingComment&#39;,
          fix: function (fixer) {
            // 自动修复
          },
        });
      }
    },
  };
}
登入後複製

看下完成后的效果:

效果对比

我们再来对比下优化前后的区别:


优化前 优化后
自动提取埋点信息,生成埋点文档
自动给埋点注释添加自定义 tag(@log)
自动给埋点注释添加上报的埋点信息
自动给埋点注释添加路由信息
自动给埋点注释添加埋点描述信息
自动提示没有注释的埋点代码

优化之后除了整个流程基本都由工具自动完成,剩下一个埋点描述信息。因为埋点的描述信息只是为了让我们更好地理解这个埋点,本身并不在上报的代码中,所以工具没有办法自动生成,但是我们可以直接在产品提供的埋点文档中拷贝过来完成这一步。

总结

在项目中接入这个工具之后,可以快速地知道项目的埋点有哪些以及各个埋点所在的页面,也方便我们对埋点的梳理,同时利用导出的埋点数据开发后台应用,有效地提升了开发者效率。

这个工具的实现是在 JSDoc、webpack 和 ESLint 插件的加持下水到渠成的,说是水到渠成是因为一开始的想法只是做到第一步,先有个一键查询功能和能够输出一份文档用着先。但是第一版出来后发现要手动去处理这些埋点注释还是比较繁琐,恰巧平常开发中常见的 webpack 插件和 ESLint 插件可以很好地解决这些问题,于是便有路由依赖分析和 ESLint 插件。像是《牧羊少年奇幻之旅》中所说的,“如果你下定决心要做一件事情,整个宇宙都会合力帮助你。”

【推荐学习:web前端开发编程基础视频教程

以上是工具分享:實現前端埋點的自動化管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP與Vue:完美搭檔的前端開發利器 PHP與Vue:完美搭檔的前端開發利器 Mar 16, 2024 pm 12:09 PM

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

前端面試官常問的問題 前端面試官常問的問題 Mar 19, 2024 pm 02:24 PM

在前端開發面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和函式庫、專案經驗、演算法和資料結構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經驗以及對行業趨勢的理解。因此,應試者應充分準備這些方面,以展現自己的能力和專業知識。

C#開發經驗分享:前端與後端協同開發技巧 C#開發經驗分享:前端與後端協同開發技巧 Nov 23, 2023 am 10:13 AM

身為C#開發者,我們的開發工作通常包括前端和後端的開發,而隨著技術的發展和專案的複雜性提高,前端與後端協同開發也變得越來越重要和複雜。本文將分享一些前端與後端協同開發的技巧,以幫助C#開發者更有效率地完成開發工作。確定好介面規範前後端的協同開發離不開API介面的交互。要確保前後端協同開發順利進行,最重要的是定義好介面規格。接口規範涉及到接口的命

Django是前端還是後端?一探究竟! Django是前端還是後端?一探究竟! Jan 19, 2024 am 08:37 AM

Django是一個由Python編寫的web應用框架,它強調快速開發和乾淨方法。儘管Django是web框架,但要回答Django是前端還是後端這個問題,需要深入理解前後端的概念。前端是指使用者直接和互動的介面,後端是指伺服器端的程序,他們透過HTTP協定進行資料的互動。在前端和後端分離的情況下,前後端程式可以獨立開發,分別實現業務邏輯和互動效果,資料的交

Go語言前端技術探秘:前端開發新視野 Go語言前端技術探秘:前端開發新視野 Mar 28, 2024 pm 01:06 PM

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

web標準有哪些好處 web標準有哪些好處 Sep 20, 2023 pm 03:34 PM

web標準的好處有提供更好的跨平台相容性、可訪問性、效能、搜尋引擎排名、開發和維護成本、使用者體驗以及程式碼的可維護性和可重用性。詳細說明:1、跨平台相容性,確保網站在不同的作業系統、瀏覽器和裝置上都能正確顯示和運作;2、提高可訪問性,可以確保網站對所有使用者都是可存取的;3 、加快網站載入速度,使用者可以更快地造訪和瀏覽網站,提供更好的使用者體驗;4、提高搜尋引擎排名等等。

web標準預設的連接埠有哪些 web標準預設的連接埠有哪些 Sep 20, 2023 pm 04:05 PM

web標準預設的連接埠有:1、HTTP,預設連接埠號碼為80;2、HTTPS,預設連接埠號碼為443;3、FTP,預設連接埠號碼為21;4、SSH,預設連接埠號碼為22;5、Telnet ,預設連接埠號碼為23;6、SMTP,預設連接埠號碼為25;7、POP3,預設連接埠號碼為110;8、IMAP,預設連接埠號碼為143;9、DNS,預設連接埠號碼為53;10、RDP ,預設連接埠號碼為3389等等。

前端怎麼實現即時通訊 前端怎麼實現即時通訊 Oct 09, 2023 pm 02:47 PM

實作即時通訊的方法有WebSocket、Long Polling、Server-Sent Events、WebRTC等等。詳細介紹:1、WebSocket,它可以在客戶端和伺服器之間建立持久連接,實現即時的雙向通信,前端可以使用WebSocket API來創建WebSocket連接,並透過發送和接收訊息來實現即時通訊;2、Long Polling,是一種模擬即時通訊的技術等等

See all articles