@@ -54,8 +54,8 @@ interface IntegrationOptions {
5454 logErrors : boolean ;
5555
5656 /**
57- * When set to `false `, disables tracking of components lifecycle performance.
58- * By default, it tracks only when `Tracing` integration is also enabled.
57+ * When set to `true `, enables tracking of components lifecycle performance.
58+ * It requires `Tracing` integration to be also enabled.
5959 */
6060 tracing : boolean ;
6161
@@ -75,9 +75,10 @@ interface TracingOptions {
7575 timeout : number ;
7676 /**
7777 * List of hooks to keep track of during component lifecycle.
78- * Available hooks: https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
78+ * Available hooks: 'activate' | 'create' | 'destroy' | 'mount' | 'update'
79+ * Based on https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
7980 */
80- hooks : Hook [ ] ;
81+ hooks : Operation [ ] ;
8182}
8283
8384/** Optional metadata attached to Sentry Event */
@@ -103,19 +104,13 @@ type Hook =
103104
104105type Operation = 'activate' | 'create' | 'destroy' | 'mount' | 'update' ;
105106
106- // Mappings from lifecycle hook to corresponding operation,
107- // used to track already started measurements.
108- const OPERATIONS : { [ key in Hook ] : Operation } = {
109- activated : 'activate' ,
110- beforeCreate : 'create' ,
111- beforeDestroy : 'destroy' ,
112- beforeMount : 'mount' ,
113- beforeUpdate : 'update' ,
114- created : 'create' ,
115- deactivated : 'activate' ,
116- destroyed : 'destroy' ,
117- mounted : 'mount' ,
118- updated : 'update' ,
107+ // Mappings from operation to corresponding lifecycle hook.
108+ const HOOKS : { [ key in Operation ] : Hook [ ] } = {
109+ activate : [ 'activated' , 'deactivated' ] ,
110+ create : [ 'beforeCreate' , 'created' ] ,
111+ destroy : [ 'beforeDestroy' , 'destroyed' ] ,
112+ mount : [ 'beforeMount' , 'mounted' ] ,
113+ update : [ 'beforeUpdate' , 'updated' ] ,
119114} ;
120115
121116const COMPONENT_NAME_REGEXP = / (?: ^ | [ - _ / ] ) ( \w ) / g;
@@ -152,10 +147,10 @@ export class Vue implements Integration {
152147 Vue : getGlobalObject < any > ( ) . Vue , // tslint:disable-line:no-unsafe-any
153148 attachProps : true ,
154149 logErrors : false ,
155- tracing : true ,
150+ tracing : false ,
156151 ...options ,
157152 tracingOptions : {
158- hooks : [ 'beforeMount ' , 'mounted' , 'beforeUpdate' , 'updated '] ,
153+ hooks : [ 'mount ' , 'update ' ] ,
159154 timeout : 2000 ,
160155 trackComponents : false ,
161156 ...options . tracingOptions ,
@@ -252,7 +247,7 @@ export class Vue implements Integration {
252247 }
253248 } ;
254249
255- const childHandler = ( hook : Hook ) => {
250+ const childHandler = ( hook : Hook , operation : Operation ) => {
256251 // Skip components that we don't want to track to minimize the noise and give a more granular control to the user
257252 const shouldTrack = Array . isArray ( this . _options . tracingOptions . trackComponents )
258253 ? this . _options . tracingOptions . trackComponents . includes ( name )
@@ -263,8 +258,7 @@ export class Vue implements Integration {
263258 }
264259
265260 const now = timestampWithMs ( ) ;
266- const op = OPERATIONS [ hook ] ;
267- const span = spans [ op ] ;
261+ const span = spans [ operation ] ;
268262
269263 // On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
270264 // However, on the second call (after), it'll be already in place.
@@ -274,27 +268,40 @@ export class Vue implements Integration {
274268 } else {
275269 vm . $once ( `hook:${ hook } ` , ( ) => {
276270 if ( this . _rootSpan ) {
277- spans [ op ] = this . _rootSpan . startChild ( {
271+ spans [ operation ] = this . _rootSpan . startChild ( {
278272 description : `Vue <${ name } >` ,
279- op,
273+ op : operation ,
280274 } ) ;
281275 }
282276 } ) ;
283277 }
284278 } ;
285279
286280 // Each compomnent has it's own scope, so all activities are only related to one of them
287- this . _options . tracingOptions . hooks . forEach ( hook => {
288- const handler = rootMount ? rootHandler . bind ( this , hook ) : childHandler . bind ( this , hook ) ;
289- const currentValue = vm . $options [ hook ] ;
290-
291- if ( Array . isArray ( currentValue ) ) {
292- vm . $options [ hook ] = [ handler , ...currentValue ] ;
293- } else if ( typeof currentValue === 'function' ) {
294- vm . $options [ hook ] = [ handler , currentValue ] ;
295- } else {
296- vm . $options [ hook ] = [ handler ] ;
281+ this . _options . tracingOptions . hooks . forEach ( operation => {
282+ // Retrieve corresponding hooks from Vue lifecycle.
283+ // eg. mount => ['beforeMount', 'mounted']
284+ const internalHooks = HOOKS [ operation ] ;
285+
286+ if ( ! internalHooks ) {
287+ logger . warn ( `Unknown hook: ${ operation } ` ) ;
288+ return ;
297289 }
290+
291+ internalHooks . forEach ( internalHook => {
292+ const handler = rootMount
293+ ? rootHandler . bind ( this , internalHook )
294+ : childHandler . bind ( this , internalHook , operation ) ;
295+ const currentValue = vm . $options [ internalHook ] ;
296+
297+ if ( Array . isArray ( currentValue ) ) {
298+ vm . $options [ internalHook ] = [ handler , ...currentValue ] ;
299+ } else if ( typeof currentValue === 'function' ) {
300+ vm . $options [ internalHook ] = [ handler , currentValue ] ;
301+ } else {
302+ vm . $options [ internalHook ] = [ handler ] ;
303+ }
304+ } ) ;
298305 } ) ;
299306 } ;
300307
0 commit comments