Skip to content

Commit

Permalink
use public file method in e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
s1gr1d committed Sep 6, 2024
1 parent 7671bd9 commit ae6d51c
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 29 deletions.
6 changes: 3 additions & 3 deletions dev-packages/e2e-tests/test-applications/nuxt-3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "NODE_OPTIONS='--import ./server/instrument-sentry.mjs' nuxt preview",
"preview": "NODE_OPTIONS='--import ./public/instrument.server.mjs' nuxt preview",
"clean": "npx nuxi cleanup",
"test": "playwright test",
"test:build": "pnpm install && npx playwright install && pnpm build",
"test:assert": "pnpm test"
},
"dependencies": {
"@sentry/nuxt": "latest || *",
"nuxt": "3.12.4"
"nuxt": "3.13.1"
},
"devDependencies": {
"@nuxt/test-utils": "^3.13.1",
"@nuxt/test-utils": "^3.14.1",
"@playwright/test": "^1.44.1",
"@sentry-internal/test-utils": "link:../../../test-utils"
}
Expand Down
26 changes: 4 additions & 22 deletions packages/nuxt/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as fs from 'fs';
import * as path from 'path';
import { addPlugin, addPluginTemplate, addServerPlugin, createResolver, defineNuxtModule } from '@nuxt/kit';
import type { SentryNuxtModuleOptions } from './common/types';
import { addServerConfig } from './vite/addServerConfig';
import { addServerConfigToBuild } from './vite/addServerConfig';
import { setupSourceMaps } from './vite/sourceMaps';
import { findDefaultSdkInitFile } from './vite/utils';

export type ModuleOptions = SentryNuxtModuleOptions;

Expand Down Expand Up @@ -63,25 +62,8 @@ export default defineNuxtModule<ModuleOptions>({
if (clientConfigFile || serverConfigFile) {
setupSourceMaps(moduleOptions, nuxt);
}
if (serverConfigFile) {
addServerConfig(moduleOptions, nuxt, serverConfigFile);
if (serverConfigFile && serverConfigFile.includes('.server.config')) {
addServerConfigToBuild(moduleOptions, nuxt, serverConfigFile);
}
},
});

function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined {
const possibleFileExtensions = ['ts', 'js', 'mjs', 'cjs', 'mts', 'cts'];

const cwd = process.cwd();
const filePath = possibleFileExtensions
.map(e =>
path.resolve(
type === 'server'
? path.join(cwd, 'public', `instrument.${type}.${e}`)
: path.join(cwd, `sentry.${type}.config.${e}`),
),
)
.find(filename => fs.existsSync(filename));

return filePath ? path.basename(filePath) : undefined;
}
22 changes: 18 additions & 4 deletions packages/nuxt/src/vite/addServerConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,29 @@ import type { Nuxt } from '@nuxt/schema';
import type { SentryNuxtModuleOptions } from '../common/types';

/**
* Adds the `server.config.ts` file to the `.output` directory to be able to reference this file in the node --import option.
* Adds the `server.config.ts` file as `instrument-sentry.mjs` to the `.output` directory to be able to reference this file in the node --import option.
*
* 1. Adding the file as a rollup import, so it is included in the build (automatically transpiles the file).
* 2. Copying the file to the `.output` directory after the build process is finished.
*/
export function addServerConfig(moduleOptions: SentryNuxtModuleOptions, nuxt: Nuxt, serverConfigFile: string): void {
export function addServerConfigToBuild(
moduleOptions: SentryNuxtModuleOptions,
nuxt: Nuxt,
serverConfigFile: string,
): void {
if (moduleOptions.debug) {
// eslint-disable-next-line no-console
console.log(
'[Sentry] Using your `sentry.server.config` file for the server-side Sentry configuration. In case you have a `public/instrument.server` file, it will be ignored.',
);
}

nuxt.hook('vite:extendConfig', async (viteInlineConfig, _env) => {
if (
typeof viteInlineConfig?.build?.rollupOptions?.input === 'object' &&
'server' in viteInlineConfig.build.rollupOptions.input
) {
// Create a rollup entry for the server config to add it to the build
// Create a rollup entry for the server config to add it as `instrument-sentry.mjs` to the build
(viteInlineConfig.build.rollupOptions.input as { [entryName: string]: string })['instrument-sentry'] =
createResolver(nuxt.options.srcDir).resolve(`/${serverConfigFile}`);
}
Expand All @@ -34,7 +46,9 @@ export function addServerConfig(moduleOptions: SentryNuxtModuleOptions, nuxt: Nu

if (moduleOptions.debug) {
// eslint-disable-next-line no-console
console.log('[Sentry] Successfully added the `sentry.server.config` file to the `.output` directory');
console.log(
'[Sentry] Successfully added the content of the `sentry.server.config` file as `instrument-sentry.mjs` to the `.output/server` directory',
);
}
} catch (error) {
if (moduleOptions.debug) {
Expand Down
28 changes: 28 additions & 0 deletions packages/nuxt/src/vite/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as fs from 'fs';
import * as path from 'path';

/**
* Find the default SDK init file for the given type (client or server).
* The sentry.server.config file is prioritized over the instrument.server file.
*/
export function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined {
const possibleFileExtensions = ['ts', 'js', 'mjs', 'cjs', 'mts', 'cts'];
const cwd = process.cwd();

const filePaths: string[] = [];
if (type === 'server') {
for (const ext of possibleFileExtensions) {
// order is important here - we want to prioritize the server.config file
filePaths.push(path.join(cwd, `sentry.${type}.config.${ext}`));
filePaths.push(path.join(cwd, 'public', `instrument.${type}.${ext}`));
}
} else {
for (const ext of possibleFileExtensions) {
filePaths.push(path.join(cwd, `sentry.${type}.config.${ext}`));
}
}

const filePath = filePaths.find(filename => fs.existsSync(filename));

return filePath ? path.basename(filePath) : undefined;
}
73 changes: 73 additions & 0 deletions packages/nuxt/test/vite/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as fs from 'fs';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { findDefaultSdkInitFile } from '../../src/vite/utils';

vi.mock('fs');

describe('findDefaultSdkInitFile', () => {
afterEach(() => {
vi.clearAllMocks();
});

it('should return the server file if it exists', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return !(filePath instanceof URL) && filePath.includes('sentry.server.config.js');
});

const result = findDefaultSdkInitFile('server');
expect(result).toBe('sentry.server.config.js');
});

it('should return the client file if it exists', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return !(filePath instanceof URL) && filePath.includes('sentry.client.config.js');
});

const result = findDefaultSdkInitFile('client');
expect(result).toBe('sentry.client.config.js');
});

it('should return undefined if no file exists', () => {
vi.spyOn(fs, 'existsSync').mockReturnValue(false);

const result = findDefaultSdkInitFile('server');
expect(result).toBeUndefined();
});

it('should return the server config file if server.config and instrument exist', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return (
!(filePath instanceof URL) &&
(filePath.includes('sentry.server.config.js') || filePath.includes('instrument.server.js'))
);
});

const result = findDefaultSdkInitFile('server');
expect(result).toBe('sentry.server.config.js');
});

it('should return the server file with .ts extension if it exists', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return !(filePath instanceof URL) && filePath.includes('sentry.server.config.ts');
});

const result = findDefaultSdkInitFile('server');
expect(result).toBe('sentry.server.config.ts');
});

it('should return the client file with .mjs extension if it exists', () => {
vi.spyOn(fs, 'existsSync').mockImplementation(filePath => {
return !(filePath instanceof URL) && filePath.includes('sentry.client.config.mjs');
});

const result = findDefaultSdkInitFile('client');
expect(result).toBe('sentry.client.config.mjs');
});

it('should return undefined if no file with specified extensions exists', () => {
vi.spyOn(fs, 'existsSync').mockReturnValue(false);

const result = findDefaultSdkInitFile('server');
expect(result).toBeUndefined();
});
});

0 comments on commit ae6d51c

Please sign in to comment.