老大對我目前手上的項目引入了阿里雲ARMS前端監控,可是我本身對ARMS SDK的API以及如何注入到Vue中不是很懂,所以這篇博客誕生了。前端
/** * 阿里前端監控 * 配置文檔 https://www.npmjs.com/package/alife-logger */ import BrowerLogger from 'alife-logger'; const logger = (() => { if (process.env.NODE_ENV === 'production') { try { return BrowerLogger.singleton({ pid: '241asf2342141@dfaf1', // 這是項目ID,新建一個應用站點後自動生成,在單個應用站點內部的`設置->應用設置`查看 imgUrl: 'https://arms-retcode.aliyuncs.com/r.png?', // 日誌上傳地址,源碼中默認值就是這個地址 enableSPA: true, // 是否監聽頁面的 hashchange 事件並從新上報 PV,適用於單頁面應用場景 sendResource: true, // 是否上報資源數據 }); } catch (e) { // eslint-disable-next-line no-console console.error('init logger fail', e); } } else { return { error() {}, }; } })(); export default logger;
開啓單頁應用的PV上報。
就拿vue來講,經過vue-router進行頁面切換時,每一個url都會帶一個#,例如從http://foo.com/#/bar
跳轉到http://bar.com/#/baz
。
嚴格意義上說,這不算是一次page change,可是因爲咱們是單頁應用,因此也算是一次page change,所以咱們須要一個事件去監聽#後面的內容的變化,這個事件就是hashchange,每次#後面的內容變化,都會算作一次PV。
關於hashchange的更多細節,能夠到一些低調的瀏覽器事件查看,或者到[hashchange](
https://developer.mozilla.org...。vue
main.jsnode
import arms from '@/arms'; Vue.config.errorHandler = (err, vm, info) => { arms.error(err, { filename: `${vm.$vnode.tag}, ${info}`}); };
Vue.config是一個對象,包含vue的一些全局配置,能夠在啓動應用以前修改屬性。
它包含slient
,optionMergeStrategies
,devtools
,errorHandler
,warnHandler
,ignoreElements
,keyCodes
,performance
,productionTip
等配置項。git
此次主要的任務是學習Vue.config.errorHandler,附帶着把Vue.config.productionTip = false也瞭解下。github
在組件渲染函數或者watchers期間,分配一個處理器給uncaught error。vue-router
Vue.config.errorHandler = function (err, vm, info) { // err 錯誤信息 // vm Vue實例 // info Vue-specific error信息 }
關鍵詞:捕獲錯誤 捕獲uncaught error 前端錯誤追蹤 避免前端頁面崩潰express
vm.$on('eventName', handler)
。Vue.config.errorHandler源碼:npm
function globalHandleError (err, vm, info) { if (config.errorHandler) { try { return config.errorHandler.call(null, err, vm, info) // 有定義就返回自定義的運行後的Vue的config.errorHandler。能夠用於將錯誤上報給第三方前端錯誤追蹤服務,例如阿里雲ARMS,Sentry,Bugsnag等等 } catch (e) { logError(e, null, 'config.errorHandler'); // 運行錯誤的話拋出異常 } } logError(err, vm, info); // 當errorHandler爲undefined時,被捕獲的錯誤會經過console.error輸出避免崩潰,其實也就是默認會捕獲uncaught error而且輸出,避免崩潰。 }
logError源碼:segmentfault
function logError (err, vm, info) { { warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm); } /* istanbul ignore else */ if ((inBrowser || inWeex) && typeof console !== 'undefined') { console.error(err); } else { throw err } }
arms.error(err, { filename: `${vm.$vnode.tag}, ${info}`});
?https://www.npmjs.com/package... 給出了錯誤信息上報接口的文檔。__bl.error(error, pos)
error爲JS的Error對象,filename是pos的一個key,filename後面的模板字符串是爲了惟必定位錯誤信息文件。瀏覽器
http://foo.com/#/friend 的vm.$vnode.tag爲vue-component-136-record。
http://foo.com/#/autoreply 的vm.$node.tag爲vue-component-138-autoreply。
源碼在vnode.js。
vue/src/core/util/error.js 源碼會暴露一個handlerError函數,經過搜索'handlerEroor'關鍵詞,找到可能輸出的值。
handleError(err, vm, `@render`); // src/platforms/weex/runtime/recycle-list/render-component-template.js handleError(e, vm, `render`); // src/core/instance/render.js handleError(e, vm, `event handler for "${event}"`); // src/core/instance/events.js handleError(e, vnode.context, `directive ${dir.name} ${hook} hook`); // src/core/vdom/modules/directives.js handleError(e, vm, `getter for watcher "${this.expression}"`); // src/core/observer/watcher.js handleError(e, ctx, 'nextTick'); // src/core/util/next-tick.js handleError(e, vm, `${hook} hook`); // src/core/instance/lifecycle.js handleError(e, vm, `data()`); // src/core/instance/state.js handleError(e, ctx, 'nextTick'); // packages/weex-vue-framework/factory.js,dist目錄下的文件基本都有此方法 handleError(e, vm, (hook + " hook"));// packages/vue-server-renderer/build.js,basic.js
filename: `${vm.$vnode.tag}, ${info}`
對應ARMS前端監控平臺的什麼位置?在訪問明細表格的File字段,能夠找到filename對應的信息,例如File: vue-component-109-chatFriend, nextTick
。
期待和你們交流,共同進步,歡迎你們加入我建立的與前端開發密切相關的技術討論小組:
- SegmentFault技術圈:ES新規範語法糖
- SegmentFault專欄:趁你還年輕,作個優秀的前端工程師
- 知乎專欄:趁你還年輕,作個優秀的前端工程師
- Github博客: 趁你還年輕233的我的博客
- 前端開發QQ羣:660634678
- 微信公衆號: 人獸鬼 / excellent_developers
努力成爲優秀前端工程師!