Simplify plugin and reduce scope

This commit is contained in:
Chris 2023-09-07 14:53:36 +02:00
parent 09de89b6fe
commit a44d8bb53a
9 changed files with 30 additions and 184 deletions

View file

@ -92,7 +92,6 @@ To configure this adapter, pass an object to the `vercel()` function call in `as
**Added in:** `@astrojs/vercel@3.8.0` **Added in:** `@astrojs/vercel@3.8.0`
You can enable [Vercel Web Analytics](https://vercel.com/docs/concepts/analytics) by setting `webAnalytics: { enabled: true }`. This will inject Vercels tracking scripts into all of your pages. You can enable [Vercel Web Analytics](https://vercel.com/docs/concepts/analytics) by setting `webAnalytics: { enabled: true }`. This will inject Vercels tracking scripts into all of your pages.
You can also pass [configuration options](https://vercel.com/docs/concepts/analytics/package) like `mode` and `debug` via the `config` property inside `webAnalytics`.
```js ```js
// astro.config.mjs // astro.config.mjs
@ -109,25 +108,6 @@ export default defineConfig({
}); });
``` ```
#### `beforeSend`
`beforeSend` is a function that can modify analytics event data before it's sent to Vercel.
Define this function in a separate file at the root of your project called `vercel-web-analytics.ts` (or `vercel-web-analytics.js` if you're not using TypeScript).
```ts
// vercel-web-analytics.ts
import type { VercelWebAnalyticsBeforeSend } from '@astrojs/vercel';
export const beforeSend: VercelWebAnalyticsBeforeSend = (event) => {
// Ignore all events that have a `/private` inside the URL
if (event.url.includes('/private')) {
return null;
}
return event;
};
```
### Speed Insights ### Speed Insights
You can enable [Vercel Speed Insights](https://vercel.com/docs/concepts/speed-insights) by setting `speedInsights: { enabled: true }`. This will collect and send Web Vital data to Vercel. You can enable [Vercel Speed Insights](https://vercel.com/docs/concepts/speed-insights) by setting `speedInsights: { enabled: true }`. This will collect and send Web Vital data to Vercel.

View file

@ -1,90 +1,30 @@
import { AstroError } from 'astro/errors';
import type { AnalyticsProps } from '@vercel/analytics';
import { fileURLToPath } from 'url';
import { existsSync } from 'node:fs';
import type { AstroIntegrationLogger } from 'astro';
export type VercelWebAnalyticsConfig = { export type VercelWebAnalyticsConfig = {
enabled: boolean; enabled: boolean;
config?: Omit<AnalyticsProps, 'beforeSend'>;
}; };
export function getWebAnalyticsViteConfig(enabled?: boolean) {
if (enabled) {
return {
build: {
rollupOptions: {
external: ['@vercel/analytics'],
},
},
};
}
return {};
}
async function getWebAnalyticsFunctions({
root,
logger,
}: {
root: URL;
logger: AstroIntegrationLogger;
}) {
const tsPath = fileURLToPath(new URL('./vercel-web-analytics.ts', root));
const jsPath = fileURLToPath(new URL('./vercel-web-analytics.js', root));
const tsFileExists = existsSync(tsPath);
const jsFileExists = existsSync(jsPath);
if (tsFileExists && jsFileExists) {
logger.warn(
`@astrojs/vercel: Both \`vercel-web-analytics.ts\` and \`vercel-web-analytics.js\` exist. Using \`vercel-web-analytics.ts\`.`
);
}
if (!tsFileExists && !jsFileExists) {
logger.debug(
`@astrojs/vercel: \`vercel-web-analytics.ts\` or \`vercel-web-analytics.js\` not found.`
);
return {
beforeSend: undefined,
};
}
const functions = await import(
tsFileExists ? /* @vite-ignore */ tsPath : /* @vite-ignore */ jsPath
);
if (typeof functions.beforeSend !== 'function') {
throw new AstroError(
`@astrojs/vercel: \`vercel-web-analytics.${
tsFileExists ? 'ts' : 'js'
}\` must export a \`beforeSend\` function.`
);
}
return {
beforeSend: functions.beforeSend,
};
}
export async function getInjectableWebAnalyticsContent({ export async function getInjectableWebAnalyticsContent({
config, mode,
astro,
}: { }: {
config: Omit<AnalyticsProps, 'beforeSend'> | undefined; mode: 'development' | 'production';
astro: {
root: URL;
logger: AstroIntegrationLogger;
};
}) { }) {
const { beforeSend } = await getWebAnalyticsFunctions(astro); const base = `window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };`;
return `import { inject } from '@vercel/analytics'; if (mode === 'development') {
inject({ return `
mode: ${config?.mode}, ${base}
beforeSend: ${beforeSend}, var script = document.createElement('script');
debug: ${config?.debug} script.defer = true;
});`; script.src = 'https://cdn.vercel-insights.com/v1/script.debug.js';
var head = document.querySelector('head');
head.appendChild(script);
`;
}
return `${base}
var script = document.createElement('script');
script.defer = true;
script.src = '/_vercel/insights/script.js';
var head = document.querySelector('head');
head.appendChild(script);
`;
} }

View file

@ -16,7 +16,6 @@ import { getRedirects } from '../lib/redirects.js';
import { generateEdgeMiddleware } from './middleware.js'; import { generateEdgeMiddleware } from './middleware.js';
import { import {
getInjectableWebAnalyticsContent, getInjectableWebAnalyticsContent,
getWebAnalyticsViteConfig,
type VercelWebAnalyticsConfig, type VercelWebAnalyticsConfig,
} from '../lib/web-analytics.js'; } from '../lib/web-analytics.js';
import { import {
@ -148,16 +147,9 @@ export default function vercelServerless({
} }
injectScript( injectScript(
'page', 'head-inline',
await getInjectableWebAnalyticsContent({ await getInjectableWebAnalyticsContent({
config: { mode: command === 'dev' ? 'development' : 'production',
...(webAnalytics?.config || {}),
mode: command === 'dev' ? 'development' : 'production',
},
astro: {
root: config.root,
logger,
},
}) })
); );
} }
@ -173,7 +165,6 @@ export default function vercelServerless({
server: new URL('./dist/', config.root), server: new URL('./dist/', config.root),
}, },
vite: { vite: {
...getWebAnalyticsViteConfig(webAnalytics?.enabled || analytics),
...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics), ...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics),
ssr: { ssr: {
external: ['@vercel/nft'], external: ['@vercel/nft'],

View file

@ -10,7 +10,6 @@ import {
} from '../lib/speed-insights.js'; } from '../lib/speed-insights.js';
import { import {
getInjectableWebAnalyticsContent, getInjectableWebAnalyticsContent,
getWebAnalyticsViteConfig,
type VercelWebAnalyticsConfig, type VercelWebAnalyticsConfig,
} from '../lib/web-analytics.js'; } from '../lib/web-analytics.js';
@ -68,16 +67,9 @@ export default function vercelStatic({
} }
injectScript( injectScript(
'page', 'head-inline',
await getInjectableWebAnalyticsContent({ await getInjectableWebAnalyticsContent({
config: { mode: command === 'dev' ? 'development' : 'production',
...(webAnalytics?.config || {}),
mode: command === 'dev' ? 'development' : 'production',
},
astro: {
root: config.root,
logger,
},
}) })
); );
} }
@ -92,7 +84,6 @@ export default function vercelStatic({
redirects: false, redirects: false,
}, },
vite: { vite: {
...getWebAnalyticsViteConfig(webAnalytics?.enabled || analytics),
...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics), ...getSpeedInsightsViteConfig(speedInsights?.enabled || analytics),
}, },
...getImageConfig(imageService, imagesConfig, command), ...getImageConfig(imageService, imagesConfig, command),

View file

@ -1,10 +0,0 @@
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
adapter: vercel({
webAnalytics: {
enabled: true
}
})
});

View file

@ -1,9 +0,0 @@
{
"name": "@test/astro-vercel-with-web-analytics-enabled-output-as-server",
"version": "0.0.0",
"private": true,
"dependencies": {
"@astrojs/vercel": "workspace:*",
"astro": "workspace:*"
}
}

View file

@ -1,8 +0,0 @@
<html>
<head>
<title>One</title>
</head>
<body>
<h1>One</h1>
</body>
</html>

View file

@ -1,8 +0,0 @@
<html>
<head>
<title>Two</title>
</head>
<body>
<h1>Two</h1>
</body>
</html>

View file

@ -2,27 +2,6 @@ import { loadFixture } from './test-utils.js';
import { expect } from 'chai'; import { expect } from 'chai';
describe('Vercel Web Analytics', () => { describe('Vercel Web Analytics', () => {
describe('output: server', () => {
/** @type {import('./test-utils.js').Fixture} */
let fixture;
before(async () => {
fixture = await loadFixture({
root: './fixtures/with-web-analytics-enabled/output-as-server/',
output: 'server',
});
await fixture.build();
});
it('ensures that Vercel Web Analytics is present in the bundle', async () => {
const [page] = await fixture.readdir('../.vercel/output/static/_astro');
const bundle = await fixture.readFile(`../.vercel/output/static/_astro/${page}`);
expect(bundle).to.contain('/_vercel/insights');
});
});
describe('output: static', () => { describe('output: static', () => {
/** @type {import('./test-utils.js').Fixture} */ /** @type {import('./test-utils.js').Fixture} */
let fixture; let fixture;
@ -35,12 +14,12 @@ describe('Vercel Web Analytics', () => {
await fixture.build(); await fixture.build();
}); });
it('ensures that Vercel Web Analytics is present in the bundle', async () => { it('ensures that Vercel Web Analytics is present in the header', async () => {
const [page] = await fixture.readdir('../.vercel/output/static/_astro'); const pageOne = await fixture.readFile('../.vercel/output/static/one/index.html');
const pageTwo = await fixture.readFile('../.vercel/output/static/two/index.html');
const bundle = await fixture.readFile(`../.vercel/output/static/_astro/${page}`); expect(pageOne).to.contain('/_vercel/insights/script.js');
expect(pageTwo).to.contain('/_vercel/insights/script.js');
expect(bundle).to.contain('/_vercel/insights');
}); });
}); });
}); });