Skip to content

Commit ba9999f

Browse files
authored
ref(vue): Convert Vue integration to use functional approach (#10218)
Wanted to test out integration changes, so decided try it with Vue integration.
1 parent 583d720 commit ba9999f

File tree

4 files changed

+42
-56
lines changed

4 files changed

+42
-56
lines changed

packages/vue/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ export { init } from './sdk';
44
export { vueRouterInstrumentation } from './router';
55
export { attachErrorHandler } from './errorhandler';
66
export { createTracingMixins } from './tracing';
7-
export { VueIntegration } from './integration';
7+
export { vueIntegration, VueIntegration } from './integration';

packages/vue/src/integration.ts

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { hasTracingEnabled } from '@sentry/core';
2-
import type { Client, Hub, Integration } from '@sentry/types';
1+
import { convertIntegrationFnToClass, defineIntegration, hasTracingEnabled } from '@sentry/core';
2+
import type { Client, Integration, IntegrationClass, IntegrationFn } from '@sentry/types';
33
import { GLOBAL_OBJ, arrayify, consoleSandbox } from '@sentry/utils';
44

55
import { DEFAULT_HOOKS } from './constants';
@@ -18,55 +18,49 @@ const DEFAULT_CONFIG: VueOptions = {
1818
trackComponents: false,
1919
};
2020

21-
/**
22-
* Initialize Vue error & performance tracking.
23-
*/
24-
export class VueIntegration implements Integration {
25-
/**
26-
* @inheritDoc
27-
*/
28-
public static id: string = 'Vue';
29-
30-
/**
31-
* @inheritDoc
32-
*/
33-
public name: string;
34-
35-
private readonly _options: Partial<VueOptions>;
21+
const INTEGRATION_NAME = 'Vue';
3622

37-
public constructor(options: Partial<VueOptions> = {}) {
38-
this.name = VueIntegration.id;
39-
this._options = options;
40-
}
23+
const _vueIntegration = ((integrationOptions: Partial<VueOptions> = {}) => {
24+
return {
25+
name: INTEGRATION_NAME,
26+
// TODO v8: Remove this
27+
setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
28+
setup(client) {
29+
_setupIntegration(client, integrationOptions);
30+
},
31+
};
32+
}) satisfies IntegrationFn;
4133

42-
/** @inheritDoc */
43-
public setupOnce(_addGlobalEventProcessor: unknown, getCurrentHub: () => Hub): void {
44-
// eslint-disable-next-line deprecation/deprecation
45-
this._setupIntegration(getCurrentHub().getClient());
46-
}
34+
export const vueIntegration = defineIntegration(_vueIntegration);
4735

48-
/** Just here for easier testing */
49-
protected _setupIntegration(client: Client | undefined): void {
50-
const options: Options = { ...DEFAULT_CONFIG, ...(client && client.getOptions()), ...this._options };
36+
/**
37+
* Initialize Vue error & performance tracking.
38+
*/
39+
// eslint-disable-next-line deprecation/deprecation
40+
export const VueIntegration = convertIntegrationFnToClass(
41+
INTEGRATION_NAME,
42+
vueIntegration,
43+
) as IntegrationClass<Integration>;
5144

52-
if (!options.Vue && !options.app) {
53-
consoleSandbox(() => {
54-
// eslint-disable-next-line no-console
55-
console.warn(
56-
`[@sentry/vue]: Misconfigured SDK. Vue specific errors will not be captured.
45+
function _setupIntegration(client: Client, integrationOptions: Partial<VueOptions>): void {
46+
const options: Options = { ...DEFAULT_CONFIG, ...client.getOptions(), ...integrationOptions };
47+
if (!options.Vue && !options.app) {
48+
consoleSandbox(() => {
49+
// eslint-disable-next-line no-console
50+
console.warn(
51+
`[@sentry/vue]: Misconfigured SDK. Vue specific errors will not be captured.
5752
Update your \`Sentry.init\` call with an appropriate config option:
5853
\`app\` (Application Instance - Vue 3) or \`Vue\` (Vue Constructor - Vue 2).`,
59-
);
60-
});
61-
return;
62-
}
54+
);
55+
});
56+
return;
57+
}
6358

64-
if (options.app) {
65-
const apps = arrayify(options.app);
66-
apps.forEach(app => vueInit(app, options));
67-
} else if (options.Vue) {
68-
vueInit(options.Vue, options);
69-
}
59+
if (options.app) {
60+
const apps = arrayify(options.app);
61+
apps.forEach(app => vueInit(app, options));
62+
} else if (options.Vue) {
63+
vueInit(options.Vue, options);
7064
}
7165
}
7266

packages/vue/test/integration/VueIntegration.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Client } from '@sentry/types';
12
import { logger } from '@sentry/utils';
23
import { createApp } from 'vue';
34

@@ -36,7 +37,7 @@ describe('Sentry.VueIntegration', () => {
3637

3738
// This would normally happen through client.addIntegration()
3839
const integration = new Sentry.VueIntegration({ app });
39-
integration['_setupIntegration'](Sentry.getClient());
40+
integration['setup']?.(Sentry.getClient() as Client);
4041

4142
app.mount(el);
4243

@@ -58,7 +59,7 @@ describe('Sentry.VueIntegration', () => {
5859

5960
// This would normally happen through client.addIntegration()
6061
const integration = new Sentry.VueIntegration({ app });
61-
integration['_setupIntegration'](Sentry.getClient());
62+
integration['setup']?.(Sentry.getClient() as Client);
6263

6364
expect(warnings).toEqual([
6465
'[@sentry/vue]: Misconfigured SDK. Vue app is already mounted. Make sure to call `app.mount()` after `Sentry.init()`.',

packages/vue/test/integration/init.test.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ Update your \`Sentry.init\` call with an appropriate config option:
104104
});
105105

106106
function runInit(options: Partial<Options>): void {
107-
const hasRunBefore = Sentry.getClient()?.getIntegrationByName?.(VueIntegration.id);
108-
109107
const integration = new VueIntegration();
110108

111109
Sentry.init({
@@ -114,11 +112,4 @@ function runInit(options: Partial<Options>): void {
114112
integrations: [integration],
115113
...options,
116114
});
117-
118-
// Because our integrations API is terrible to test, we need to make sure to check
119-
// If we've already had this integration registered before
120-
// if that's the case, `setup()` will not be run, so we need to manually run it :(
121-
if (hasRunBefore) {
122-
integration['_setupIntegration'](Sentry.getClient());
123-
}
124115
}

0 commit comments

Comments
 (0)