Skip to content

Commit

Permalink
fix: next/jest does not support import.meta (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
feugy authored Nov 25, 2024
1 parent cd899aa commit b8e2c2f
Show file tree
Hide file tree
Showing 21 changed files with 246 additions and 124 deletions.
3 changes: 0 additions & 3 deletions apps/remix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,5 @@
"typescript": "^5.1.6",
"vite": "^5.1.0",
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
"node": ">=20.0.0"
}
}
2 changes: 1 addition & 1 deletion packages/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vercel/speed-insights",
"version": "1.2.0-canary.3",
"version": "1.2.0-canary.4",
"description": "Speed Insights is a tool for measuring web performance and providing suggestions for improvement.",
"keywords": [
"speed-insights",
Expand Down
14 changes: 14 additions & 0 deletions packages/web/src/astro/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ const paramsStr = JSON.stringify(Astro.params);
<script>
import { injectSpeedInsights, computeRoute } from '../index.mjs';

function getBasePath(): string | undefined {
// !! important !!
// do not access env variables using import.meta.env[varname]
// some bundles won't replace the value at build time.
try {
return import.meta.env.PUBLIC_VERCEL_OBSERVABILITY_BASEPATH as
| string
| undefined;
} catch {
// do nothing
}
}

customElements.define(
'vercel-speed-insights',
class VercelSpeedInsights extends HTMLElement {
Expand All @@ -28,6 +41,7 @@ const paramsStr = JSON.stringify(Astro.params);
route,
...props,
framework: 'astro',
basePath: getBasePath(),
beforeSend: window.speedInsightsBeforeSend,
});
} catch (err) {
Expand Down
14 changes: 4 additions & 10 deletions packages/web/src/generic.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { name as packageName, version } from '../package.json';
import { initQueue } from './queue';
import type { SpeedInsightsProps } from './types';
import {
computeRoute,
getBasePath,
getScriptSrc,
isBrowser,
isDevelopment,
} from './utils';
import { computeRoute, getScriptSrc, isBrowser, isDevelopment } from './utils';

/**
* Injects the Vercel Speed Insights script into the page head and starts tracking page views. Read more in our [documentation](https://vercel.com/docs/speed-insights).
Expand All @@ -21,6 +15,7 @@ import {
function injectSpeedInsights(
props: SpeedInsightsProps & {
framework?: string;
basePath?: string;
} = {},
): {
setRoute: (route: string | null) => void;
Expand Down Expand Up @@ -51,11 +46,10 @@ function injectSpeedInsights(
if (props.route) {
script.dataset.route = props.route;
}
const basePath = getBasePath();
if (props.endpoint) {
script.dataset.endpoint = props.endpoint;
} else if (basePath) {
script.dataset.endpoint = `${basePath}/speed-insights/vitals`;
} else if (props.basePath) {
script.dataset.endpoint = `${props.basePath}/speed-insights/vitals`;
}
if (props.dsn) {
script.dataset.dsn = props.dsn;
Expand Down
11 changes: 9 additions & 2 deletions packages/web/src/nextjs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@
import React, { Suspense } from 'react';
import { SpeedInsights as SpeedInsightsScript } from '../react';
import type { SpeedInsightsProps } from '../types';
import { useRoute } from './utils';
import { getBasePath, useRoute } from './utils';

type Props = Omit<SpeedInsightsProps, 'route'>;

function SpeedInsightsComponent(props: Props): React.ReactElement {
const route = useRoute();

return <SpeedInsightsScript route={route} {...props} framework="next" />;
return (
<SpeedInsightsScript
route={route}
{...props}
framework="next"
basePath={getBasePath()}
/>
);
}

export function SpeedInsights(props: Props): null {
Expand Down
30 changes: 30 additions & 0 deletions packages/web/src/nextjs/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { afterEach, describe, it, expect } from 'vitest';
import { getBasePath } from './utils';

describe('getBasePath()', () => {
const processSave = { ...process };
const envSave = { ...process.env };

afterEach(() => {
global.process = { ...processSave };
process.env = { ...envSave };
});

it('returns null without process', () => {
// @ts-expect-error -- yes, we want to completely drop process for this test!!
global.process = undefined;
expect(getBasePath()).toBeUndefined();
});

it('returns null without process.env', () => {
// @ts-expect-error -- yes, we want to completely drop process.env for this test!!
process.env = undefined;
expect(getBasePath()).toBeUndefined();
});

it('returns basepath set for Nextjs', () => {
const basepath = `/_vercel-${Math.random()}/insights`;
process.env.NEXT_PUBLIC_VERCEL_OBSERVABILITY_BASEPATH = basepath;
expect(getBasePath()).toBe(basepath);
});
});
11 changes: 11 additions & 0 deletions packages/web/src/nextjs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ export const useRoute = (): string | null => {
: Object.fromEntries(searchParams.entries());
return computeRoute(path, finalParams);
};

export function getBasePath(): string | undefined {
// !! important !!
// do not access env variables using process.env[varname]
// some bundles won't replace the value at build time.
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- we can't use optionnal here, it'll break if process does not exist.
if (typeof process === 'undefined' || typeof process.env === 'undefined') {
return undefined;
}
return process.env.NEXT_PUBLIC_VERCEL_OBSERVABILITY_BASEPATH;
}
5 changes: 4 additions & 1 deletion packages/web/src/react/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import { useEffect, useRef } from 'react';
import type { SpeedInsightsProps } from '../types';
import { computeRoute, injectSpeedInsights } from '../generic';
import { getBasePath } from './utils';

export function SpeedInsights(
props: SpeedInsightsProps & {
framework?: string;
basePath?: string;
},
): JSX.Element | null {
useEffect(() => {
Expand All @@ -19,7 +21,8 @@ export function SpeedInsights(
useEffect(() => {
if (!setScriptRoute.current) {
const script = injectSpeedInsights({
framework: props.framework || 'react',
framework: props.framework ?? 'react',
basePath: props.basePath ?? getBasePath(),
...props,
});
if (script) {
Expand Down
30 changes: 30 additions & 0 deletions packages/web/src/react/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { afterEach, describe, it, expect } from 'vitest';
import { getBasePath } from './utils';

describe('getBasePath()', () => {
const processSave = { ...process };
const envSave = { ...process.env };

afterEach(() => {
global.process = { ...processSave };
process.env = { ...envSave };
});

it('returns null without process', () => {
// @ts-expect-error -- yes, we want to completely drop process for this test!!
global.process = undefined;
expect(getBasePath()).toBeUndefined();
});

it('returns null without process.env', () => {
// @ts-expect-error -- yes, we want to completely drop process.env for this test!!
process.env = undefined;
expect(getBasePath()).toBeUndefined();
});

it('returns basepath set for CRA', () => {
const basepath = `/_vercel-${Math.random()}/insights`;
process.env.REACT_APP_VERCEL_OBSERVABILITY_BASEPATH = basepath;
expect(getBasePath()).toBe(basepath);
});
});
10 changes: 10 additions & 0 deletions packages/web/src/react/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function getBasePath(): string | undefined {
// !! important !!
// do not access env variables using process.env[varname]
// some bundles won't replace the value at build time.
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- we can't use optionnal here, it'll break if process does not exist.
if (typeof process === 'undefined' || typeof process.env === 'undefined') {
return undefined;
}
return process.env.REACT_APP_VERCEL_OBSERVABILITY_BASEPATH;
}
5 changes: 3 additions & 2 deletions packages/web/src/remix/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { SpeedInsights as SpeedInsightsScript } from '../react';
import type { SpeedInsightsProps } from '../types';
import { useRoute } from './utils';
import { getBasePath, useRoute } from './utils';

export function SpeedInsights(
props: Omit<SpeedInsightsProps, 'route'>,
Expand All @@ -10,9 +10,10 @@ export function SpeedInsights(

return (
<SpeedInsightsScript
{...(route && { route })}
route={route}
{...props}
framework="remix"
basePath={getBasePath()}
/>
);
}
24 changes: 24 additions & 0 deletions packages/web/src/remix/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { afterEach, describe, it, expect } from 'vitest';
import { getBasePath } from './utils';

describe('getBasePath()', () => {
const processSave = { ...process };
const envSave = { ...process.env };

afterEach(() => {
global.process = { ...processSave };
process.env = { ...envSave };
});

it('returns basepath set for Remix', () => {
const basepath = `/_vercel-${Math.random()}/insights`;
import.meta.env.VITE_VERCEL_OBSERVABILITY_BASEPATH = basepath;
expect(getBasePath()).toBe(basepath);
});

it('returns null without import.meta', () => {
// @ts-expect-error -- yes, we want to completely drop import.meta.env for this test!!
import.meta.env = undefined;
expect(getBasePath()).toBeUndefined();
});
});
13 changes: 13 additions & 0 deletions packages/web/src/remix/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,16 @@ export const useRoute = (): string | null => {

return computeRoute(location.pathname, params as never);
};

export function getBasePath(): string | undefined {
// !! important !!
// do not access env variables using import.meta.env[varname]
// some bundles won't replace the value at build time.
try {
return import.meta.env.VITE_VERCEL_OBSERVABILITY_BASEPATH as
| string
| undefined;
} catch {
// do nothing
}
}
2 changes: 2 additions & 0 deletions packages/web/src/sveltekit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
injectSpeedInsights as genericInject,
type SpeedInsightsProps,
} from '../generic';
import { getBasePath } from './utils';
import { page } from '$app/stores';
import { browser } from '$app/environment';
import type {} from '@sveltejs/kit'; // don't remove, ensures ambient types for $app/* are loaded
Expand All @@ -16,6 +17,7 @@ export function injectSpeedInsights(
route: get(page).route?.id,
...props,
framework: 'sveltekit',
basePath: getBasePath(),
});

if (speedInsights) {
Expand Down
24 changes: 24 additions & 0 deletions packages/web/src/sveltekit/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { afterEach, describe, it, expect } from 'vitest';
import { getBasePath } from './utils';

describe('getBasePath()', () => {
const processSave = { ...process };
const envSave = { ...process.env };

afterEach(() => {
global.process = { ...processSave };
process.env = { ...envSave };
});

it('returns basepath set for Sveltekit', () => {
const basepath = `/_vercel-${Math.random()}/insights`;
import.meta.env.VITE_VERCEL_OBSERVABILITY_BASEPATH = basepath;
expect(getBasePath()).toBe(basepath);
});

it('returns null without import.meta', () => {
// @ts-expect-error -- yes, we want to completely drop import.meta.env for this test!!
import.meta.env = undefined;
expect(getBasePath()).toBeUndefined();
});
});
12 changes: 12 additions & 0 deletions packages/web/src/sveltekit/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function getBasePath(): string | undefined {
// !! important !!
// do not access env variables using import.meta.env[varname]
// some bundles won't replace the value at build time.
try {
return import.meta.env.VITE_VERCEL_OBSERVABILITY_BASEPATH as
| string
| undefined;
} catch {
// do nothing
}
}
Loading

0 comments on commit b8e2c2f

Please sign in to comment.