Skip to content

Commit d6e225d

Browse files
committed
detect by plugin name
1 parent d632fe8 commit d6e225d

File tree

2 files changed

+61
-26
lines changed

2 files changed

+61
-26
lines changed

packages/tanstackstart-react/src/vite/copyInstrumentationFile.ts

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,35 @@ export function makeCopyInstrumentationFilePlugin(): Plugin {
2020
enforce: 'post',
2121

2222
configResolved(resolvedConfig: ResolvedConfig) {
23-
// Nitro case: read server dir from the nitro environment config
24-
// Vite 6 environment configs are not part of the public type definitions yet,
25-
// so we need to access them via an index signature.
26-
const environments = (resolvedConfig as Record<string, unknown>)['environments'] as
27-
| Record<string, { build?: { rollupOptions?: { output?: { dir?: string } | Array<{ dir?: string }> } } }>
28-
| undefined;
29-
const nitroEnv = environments?.nitro;
30-
if (nitroEnv) {
31-
const rollupOutput = nitroEnv.build?.rollupOptions?.output;
32-
const dir = Array.isArray(rollupOutput) ? rollupOutput[0]?.dir : rollupOutput?.dir;
33-
if (dir) {
34-
serverOutputDir = dir;
35-
return;
36-
}
37-
}
38-
39-
// Cloudflare/Netlify case: detect by plugin name
4023
const plugins = resolvedConfig.plugins || [];
41-
const hasCloudflareOrNetlify = plugins.some(p => /cloudflare|netlify/i.test(p.name));
42-
if (hasCloudflareOrNetlify) {
24+
const hasPlugin = (name: string): boolean => plugins.some(p => p.name === name);
25+
26+
if (hasPlugin('nitro')) {
27+
// Nitro case: read server dir from the nitro environment config
28+
// Vite 6 environment configs are not part of the public type definitions yet,
29+
// so we need to access them via an index signature.
30+
const environments = (resolvedConfig as Record<string, unknown>)['environments'] as
31+
| Record<string, { build?: { rollupOptions?: { output?: { dir?: string } | Array<{ dir?: string }> } } }>
32+
| undefined;
33+
const nitroEnv = environments?.nitro;
34+
if (nitroEnv) {
35+
const rollupOutput = nitroEnv.build?.rollupOptions?.output;
36+
const dir = Array.isArray(rollupOutput) ? rollupOutput[0]?.dir : rollupOutput?.dir;
37+
if (dir) {
38+
serverOutputDir = dir;
39+
}
40+
}
41+
} else if (hasPlugin('cloudflare') || hasPlugin('netlify')) {
4342
serverOutputDir = path.resolve(resolvedConfig.root, 'dist', 'server');
43+
} else {
44+
consoleSandbox(() => {
45+
// eslint-disable-next-line no-console
46+
console.warn(
47+
'[Sentry TanStack Start] Could not determine server output directory. ' +
48+
'Could not detect nitro, cloudflare, or netlify vite plugin. ' +
49+
'The instrument.server.mjs file will not be copied to the build output automatically.',
50+
);
51+
});
4452
}
4553
},
4654

packages/tanstackstart-react/test/vite/copyInstrumentationFile.test.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('makeCopyInstrumentationFilePlugin()', () => {
4545
it('detects Nitro environment and reads output dir', () => {
4646
const resolvedConfig = {
4747
root: '/project',
48-
plugins: [],
48+
plugins: [{ name: 'nitro' }],
4949
environments: {
5050
nitro: {
5151
build: {
@@ -71,7 +71,7 @@ describe('makeCopyInstrumentationFilePlugin()', () => {
7171
it('detects Nitro environment with array rollup output', () => {
7272
const resolvedConfig = {
7373
root: '/project',
74-
plugins: [],
74+
plugins: [{ name: 'nitro' }],
7575
environments: {
7676
nitro: {
7777
build: {
@@ -94,7 +94,7 @@ describe('makeCopyInstrumentationFilePlugin()', () => {
9494
it('detects Cloudflare plugin and sets dist/server as output dir', () => {
9595
const resolvedConfig = {
9696
root: '/project',
97-
plugins: [{ name: 'vite-plugin-cloudflare' }],
97+
plugins: [{ name: 'cloudflare' }],
9898
} as unknown as ResolvedConfig;
9999

100100
(plugin.configResolved as AnyFunction)(resolvedConfig);
@@ -108,7 +108,7 @@ describe('makeCopyInstrumentationFilePlugin()', () => {
108108
it('detects Netlify plugin and sets dist/server as output dir', () => {
109109
const resolvedConfig = {
110110
root: '/project',
111-
plugins: [{ name: 'netlify-plugin' }],
111+
plugins: [{ name: 'netlify' }],
112112
} as unknown as ResolvedConfig;
113113

114114
(plugin.configResolved as AnyFunction)(resolvedConfig);
@@ -125,19 +125,42 @@ describe('makeCopyInstrumentationFilePlugin()', () => {
125125
plugins: [{ name: 'some-other-plugin' }],
126126
} as unknown as ResolvedConfig;
127127

128+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
129+
128130
(plugin.configResolved as AnyFunction)(resolvedConfig);
129131

130132
(plugin.closeBundle as AnyFunction)();
131133

132134
expect(fs.promises.access).not.toHaveBeenCalled();
135+
136+
warnSpy.mockRestore();
137+
});
138+
139+
it('logs a warning when no recognized deployment plugin is detected', () => {
140+
const resolvedConfig = {
141+
root: '/project',
142+
plugins: [{ name: 'some-other-plugin' }],
143+
} as unknown as ResolvedConfig;
144+
145+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
146+
147+
(plugin.configResolved as AnyFunction)(resolvedConfig);
148+
149+
expect(warnSpy).toHaveBeenCalledWith(
150+
'[Sentry TanStack Start] Could not determine server output directory. ' +
151+
'Could not detect nitro, cloudflare, or netlify vite plugin. ' +
152+
'The instrument.server.mjs file will not be copied to the build output automatically.',
153+
);
154+
155+
warnSpy.mockRestore();
133156
});
134157
});
135158

136159
describe('closeBundle', () => {
137160
it('copies instrumentation file when it exists and output dir is set', async () => {
138161
const resolvedConfig = {
139162
root: '/project',
140-
plugins: [],
163+
plugins: [{ name: 'nitro' }],
141164
environments: {
142165
nitro: {
143166
build: {
@@ -176,18 +199,22 @@ describe('makeCopyInstrumentationFilePlugin()', () => {
176199
plugins: [{ name: 'some-other-plugin' }],
177200
} as unknown as ResolvedConfig;
178201

202+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
203+
179204
(plugin.configResolved as AnyFunction)(resolvedConfig);
180205

181206
await (plugin.closeBundle as AnyFunction)();
182207

183208
expect(fs.promises.access).not.toHaveBeenCalled();
184209
expect(fs.promises.copyFile).not.toHaveBeenCalled();
210+
211+
warnSpy.mockRestore();
185212
});
186213

187214
it('does nothing when instrumentation file does not exist', async () => {
188215
const resolvedConfig = {
189216
root: '/project',
190-
plugins: [],
217+
plugins: [{ name: 'nitro' }],
191218
environments: {
192219
nitro: {
193220
build: {
@@ -214,7 +241,7 @@ describe('makeCopyInstrumentationFilePlugin()', () => {
214241
it('logs a warning when copy fails', async () => {
215242
const resolvedConfig = {
216243
root: '/project',
217-
plugins: [],
244+
plugins: [{ name: 'nitro' }],
218245
environments: {
219246
nitro: {
220247
build: {

0 commit comments

Comments
 (0)