Skip to content

Commit 5eb3369

Browse files
committed
Read Remix version from dependency module.
1 parent 30f98a0 commit 5eb3369

File tree

6 files changed

+56
-24
lines changed

6 files changed

+56
-24
lines changed

packages/remix/src/client/performance.tsx

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import type { ErrorBoundaryProps } from '@sentry/react';
2-
import { getCurrentHub, WINDOW, withErrorBoundary } from '@sentry/react';
2+
import { WINDOW, withErrorBoundary } from '@sentry/react';
33
import type { Transaction, TransactionContext } from '@sentry/types';
44
import { isNodeEnv, logger } from '@sentry/utils';
55
import * as React from 'react';
66

7-
import { getFutureFlagsBrowser } from '../utils/futureFlags';
8-
import type { RemixOptions } from '../utils/remixOptions';
7+
import { getFutureFlagsBrowser, readRemixVersionFromLoader } from '../utils/futureFlags';
98

109
const DEFAULT_TAGS = {
1110
'routing.instrumentation': 'remix-router',
@@ -41,13 +40,6 @@ let _useMatches: UseMatches;
4140
let _customStartTransaction: (context: TransactionContext) => Transaction | undefined;
4241
let _startTransactionOnLocationChange: boolean;
4342

44-
function isRemixV2(): boolean {
45-
const client = getCurrentHub().getClient();
46-
const opt = client && (client.getOptions() as RemixOptions);
47-
48-
return (opt && opt.isRemixV2) || getFutureFlagsBrowser()?.v2_errorBoundary || false;
49-
}
50-
5143
function getInitPathName(): string | undefined {
5244
if (WINDOW && WINDOW.location) {
5345
return WINDOW.location.pathname;
@@ -56,6 +48,10 @@ function getInitPathName(): string | undefined {
5648
return undefined;
5749
}
5850

51+
function isRemixV2(remixVersion: number | undefined): boolean {
52+
return remixVersion === 2 || getFutureFlagsBrowser()?.v2_errorBoundary || false;
53+
}
54+
5955
/**
6056
* Creates a react-router v6 instrumention for Remix applications.
6157
*
@@ -162,17 +158,17 @@ export function withSentry<P extends Record<string, unknown>, R extends React.FC
162158

163159
isBaseLocation = false;
164160

165-
if (!isRemixV2() && options.wrapWithErrorBoundary) {
166-
// @ts-ignore Setting more specific React Component typing for `R` generic above
161+
if (!isRemixV2(readRemixVersionFromLoader()) && options.wrapWithErrorBoundary) {
162+
// @ts-expect-error Setting more specific React Component typing for `R` generic above
167163
// will break advanced type inference done by react router params
168164
return withErrorBoundary(OrigApp, options.errorBoundaryOptions)(props);
169165
}
170-
// @ts-ignore Setting more specific React Component typing for `R` generic above
166+
// @ts-expect-error Setting more specific React Component typing for `R` generic above
171167
// will break advanced type inference done by react router params
172168
return <OrigApp {...props} />;
173169
};
174170

175-
// @ts-ignore Setting more specific React Component typing for `R` generic above
171+
// @ts-expect-error Setting more specific React Component typing for `R` generic above
176172
// will break advanced type inference done by react router params
177173
return SentryRoot;
178174
}

packages/remix/src/index.client.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable import/export */
2-
import type { BrowserOptions } from '@sentry/react';
32
import { configureScope, init as reactInit } from '@sentry/react';
43

54
import { buildMetadata } from './utils/metadata';
@@ -12,7 +11,7 @@ export function init(options: RemixOptions): void {
1211
buildMetadata(options, ['remix', 'react']);
1312
options.environment = options.environment || process.env.NODE_ENV;
1413

15-
reactInit(options as BrowserOptions);
14+
reactInit(options);
1615

1716
configureScope(scope => {
1817
scope.setTag('runtime', 'browser');

packages/remix/src/index.server.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { NodeOptions } from '@sentry/node';
33
import { configureScope, getCurrentHub, init as nodeInit } from '@sentry/node';
44
import { logger } from '@sentry/utils';
55

6+
import { getRemixVersionFromPkg } from './utils/futureFlags';
67
import { instrumentServer } from './utils/instrumentServer';
78
import { buildMetadata } from './utils/metadata';
89
import type { RemixOptions } from './utils/remixOptions';
@@ -76,7 +77,7 @@ export function init(options: RemixOptions): void {
7677
return;
7778
}
7879

79-
instrumentServer(options.isRemixV2);
80+
instrumentServer(getRemixVersionFromPkg() === 2);
8081

8182
nodeInit(options as NodeOptions);
8283

packages/remix/src/utils/futureFlags.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
import { GLOBAL_OBJ } from '@sentry/utils';
1+
import { GLOBAL_OBJ, loadModule, parseSemver } from '@sentry/utils';
22

33
import type { FutureConfig, ServerBuild } from './vendor/types';
44

55
export type EnhancedGlobal = typeof GLOBAL_OBJ & {
66
__remixContext?: {
77
future?: FutureConfig;
8+
state?: {
9+
loaderData?: {
10+
root?: {
11+
remixVersion?: number;
12+
};
13+
};
14+
};
815
};
916
};
1017

@@ -33,3 +40,32 @@ export function getFutureFlagsBrowser(): FutureConfig | undefined {
3340
export function getFutureFlagsServer(build: ServerBuild): FutureConfig | undefined {
3441
return build.future;
3542
}
43+
44+
/**
45+
* Read Remix version from module package.json
46+
*
47+
* @returns The major version number
48+
*/
49+
export function getRemixVersionFromPkg(): number | undefined {
50+
const pkg = loadModule<{ version: string }>('@remix-run/react/package.json');
51+
const version = pkg ? pkg.version : '0.0.0';
52+
53+
return parseSemver(version).major;
54+
}
55+
56+
/**
57+
* Read Remix version from the Remix context on the browser
58+
*
59+
* @returns The major version number
60+
*/
61+
export function readRemixVersionFromLoader(): number | undefined {
62+
const window = GLOBAL_OBJ as EnhancedGlobal;
63+
64+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
65+
if (!window.__remixContext?.state?.loaderData?.root) {
66+
return;
67+
}
68+
69+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
70+
return window.__remixContext.state.loaderData.root.remixVersion;
71+
}

packages/remix/src/utils/instrumentServer.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
tracingContextFromHeaders,
1414
} from '@sentry/utils';
1515

16-
import { getFutureFlagsServer } from './futureFlags';
16+
import { getFutureFlagsServer, getRemixVersionFromPkg } from './futureFlags';
1717
import { extractData, getRequestMatch, isDeferredData, isResponse, json, matchServerRoutes } from './vendor/response';
1818
import type {
1919
AppData,
@@ -250,11 +250,13 @@ function makeWrappedRootLoader(origLoader: DataFunction): DataFunction {
250250
return async function (this: unknown, args: DataFunctionArgs): Promise<Response | AppData> {
251251
const res = await origLoader.call(this, args);
252252
const traceAndBaggage = getTraceAndBaggage();
253+
const remixVersion = getRemixVersionFromPkg();
253254

254255
if (isDeferredData(res)) {
255256
return {
256257
...res.data,
257258
...traceAndBaggage,
259+
remixVersion,
258260
};
259261
}
260262

@@ -270,7 +272,7 @@ function makeWrappedRootLoader(origLoader: DataFunction): DataFunction {
270272

271273
if (typeof data === 'object') {
272274
return json(
273-
{ ...data, ...traceAndBaggage },
275+
{ ...data, ...traceAndBaggage, remixVersion },
274276
{ headers: res.headers, statusText: res.statusText, status: res.status },
275277
);
276278
} else {
@@ -281,7 +283,7 @@ function makeWrappedRootLoader(origLoader: DataFunction): DataFunction {
281283
}
282284
}
283285

284-
return { ...res, ...traceAndBaggage };
286+
return { ...res, ...traceAndBaggage, remixVersion };
285287
};
286288
}
287289

packages/remix/src/utils/remixOptions.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,4 @@ import type { NodeOptions } from '@sentry/node';
22
import type { BrowserOptions } from '@sentry/react';
33
import type { Options } from '@sentry/types';
44

5-
export type RemixOptions = (Options | BrowserOptions | NodeOptions) & {
6-
isRemixV2?: boolean;
7-
};
5+
export type RemixOptions = Options | BrowserOptions | NodeOptions;

0 commit comments

Comments
 (0)