From dde21986b91acad8b2b4d4fcf0eea20710544bec Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Fri, 9 Oct 2026 11:42:52 +0200 Subject: [PATCH 1/3] fix(nuxt): Remove @opentelemetry/resources dev alias The alias ended up in the generated .nuxt tsconfig paths as a non-relative path, which vue-tsc rejects when typeCheck is enabled. Nothing in the Nuxt SDK's dependency tree uses @opentelemetry/resources anymore, so the alias is no longer needed. Fixes #25188 Co-Authored-By: Claude Opus 5.5 --- packages/nuxt/src/module.ts | 4 +- packages/nuxt/src/vite/utils.ts | 24 --------- packages/nuxt/test/vite/utils.test.ts | 70 --------------------------- 3 files changed, 1 insertion(+), 97 deletions(-) diff --git a/packages/nuxt/src/module.ts b/packages/nuxt/src/module.ts index f1cd456b84c6..10f22891ac2d 100644 --- a/packages/nuxt/src/module.ts +++ b/packages/nuxt/src/module.ts @@ -7,7 +7,7 @@ import type { SentryNuxtModuleOptions } from './common/types'; import { setupNitroServer } from './vite/nitroServer'; import { setupOrchestrion } from './vite/orchestrion'; import { setupSourceMaps } from './vite/sourceMaps'; -import { addOTelCommonJSImportAlias, findDefaultSdkInitFile, resolveServerApi } from './vite/utils'; +import { findDefaultSdkInitFile, resolveServerApi } from './vite/utils'; export type ModuleOptions = SentryNuxtModuleOptions; type NuxtPageSubset = { file?: string; path: string }; @@ -97,8 +97,6 @@ export default defineNuxtModule({ setupSourceMaps(moduleOptions, nuxt, addVitePlugin); } - addOTelCommonJSImportAlias(nuxt, serverApi === 'nitro3'); - let pagesData: NuxtPageSubset[] = []; nuxt.hooks.hook('pages:extend', pages => { diff --git a/packages/nuxt/src/vite/utils.ts b/packages/nuxt/src/vite/utils.ts index cab39bc95f19..fc393242b682 100644 --- a/packages/nuxt/src/vite/utils.ts +++ b/packages/nuxt/src/vite/utils.ts @@ -224,27 +224,3 @@ export function toResolvablePath(source: string): { path: string; wasFileUrl: bo return undefined; } } - -/** - * Sets up alias to work around OpenTelemetry's incomplete ESM imports. - * https://github.com/getsentry/sentry-javascript/issues/15204 - * - * OpenTelemetry's @opentelemetry/resources package has incomplete imports missing - * the .js file extensions (like execAsync for machine-id detection). This causes module resolution - * errors in certain Nuxt configurations, particularly when local Nuxt modules in Nuxt 4 are present. - * - * @see https://nuxt.com/docs/guide/concepts/esm#aliasing-libraries - */ -export function addOTelCommonJSImportAlias(nuxt: Nuxt, isNitroV3 = false): void { - if (!nuxt.options.dev || isNitroV3) { - return; - } - - if (!nuxt.options.alias) { - nuxt.options.alias = {}; - } - - if (!nuxt.options.alias['@opentelemetry/resources']) { - nuxt.options.alias['@opentelemetry/resources'] = '@opentelemetry/resources/build/src/index.js'; - } -} diff --git a/packages/nuxt/test/vite/utils.test.ts b/packages/nuxt/test/vite/utils.test.ts index 605bf368ca9c..7d1213fdc959 100644 --- a/packages/nuxt/test/vite/utils.test.ts +++ b/packages/nuxt/test/vite/utils.test.ts @@ -3,7 +3,6 @@ import * as fs from 'fs'; import * as path from 'path'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { - addOTelCommonJSImportAlias, constructFunctionReExport, constructWrappedFunctionExportQuery, extractFunctionReexportQueryParameters, @@ -428,72 +427,3 @@ export { foo_sentryWrapped as foo }; expect(result).toBe(''); }); }); - -describe('addOTelCommonJSImportAlias', () => { - it('adds alias for @opentelemetry/resources when options.alias does not exist', () => { - const nuxtMock: Nuxt = { - options: { dev: true }, - } as unknown as Nuxt; - - addOTelCommonJSImportAlias(nuxtMock); - - expect(nuxtMock.options.alias).toEqual({ - '@opentelemetry/resources': '@opentelemetry/resources/build/src/index.js', - }); - }); - - it('adds alias for @opentelemetry/resources when options.alias already exists', () => { - const nuxtMock: Nuxt = { - options: { - dev: true, - alias: { - 'existing-alias': 'some-path', - }, - }, - } as unknown as Nuxt; - - addOTelCommonJSImportAlias(nuxtMock); - - expect(nuxtMock.options.alias).toEqual({ - 'existing-alias': 'some-path', - '@opentelemetry/resources': '@opentelemetry/resources/build/src/index.js', - }); - }); - - it('does not override existing alias for @opentelemetry/resources', () => { - const nuxtMock: Nuxt = { - options: { - dev: true, - alias: { - '@opentelemetry/resources': 'some-other-path', - }, - }, - } as unknown as Nuxt; - - addOTelCommonJSImportAlias(nuxtMock); - - expect(nuxtMock.options.alias).toEqual({ - '@opentelemetry/resources': 'some-other-path', - }); - }); - - it('does not add alias when not development mode', () => { - const nuxtMock: Nuxt = { - options: {}, - } as unknown as Nuxt; - - addOTelCommonJSImportAlias(nuxtMock); - - expect(nuxtMock.options.alias).toBeUndefined(); - }); - - it('does not add alias when in Nitro v3+ (Rolldown incompatibility)', () => { - const nuxtMock: Nuxt = { - options: { dev: true }, - } as unknown as Nuxt; - - addOTelCommonJSImportAlias(nuxtMock, true); - - expect(nuxtMock.options.alias).toBeUndefined(); - }); -}); From 54e700094b8d4e8a24a03608828c2085d4bdffb0 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Fri, 9 Oct 2026 11:47:46 +0200 Subject: [PATCH 2/3] test(nuxt): Assert the module adds no aliases in dev mode Co-Authored-By: Claude Opus 5.5 --- packages/nuxt/test/module.test.ts | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 packages/nuxt/test/module.test.ts diff --git a/packages/nuxt/test/module.test.ts b/packages/nuxt/test/module.test.ts new file mode 100644 index 000000000000..99e1a1bd0b2f --- /dev/null +++ b/packages/nuxt/test/module.test.ts @@ -0,0 +1,40 @@ +import type { Nuxt } from '@nuxt/schema'; +import { describe, expect, it, vi } from 'vitest'; +import type * as viteUtils from '../src/vite/utils'; + +vi.mock('@nuxt/kit', () => ({ + addPlugin: vi.fn(), + addPluginTemplate: vi.fn(), + addTemplate: vi.fn(), + addVitePlugin: vi.fn(), + createResolver: vi.fn(() => ({ resolve: (input: string) => input })), + defineNuxtModule: (definition: unknown) => definition, +})); + +vi.mock('../src/vite/utils', async importOriginal => ({ + ...(await importOriginal()), + resolveServerApi: vi.fn(() => 'nitropack'), + findDefaultSdkInitFile: vi.fn((type: string) => `/app/sentry.${type}.config.ts`), +})); + +vi.mock('../src/vite/nitroServer', () => ({ setupNitroServer: vi.fn() })); +vi.mock('../src/vite/orchestrion', () => ({ setupOrchestrion: vi.fn() })); +vi.mock('../src/vite/sourceMaps', () => ({ setupSourceMaps: vi.fn() })); + +describe('Sentry Nuxt module', () => { + // Nuxt writes every alias into the `paths` of the generated `.nuxt/tsconfig.*.json` files, + // where vue-tsc rejects bare specifiers (TS5090) (https://github.com/getsentry/sentry-javascript/issues/25188) + it.each(['3.17.0', '4.5.2'])('does not add Nuxt aliases in dev mode (Nuxt %s)', async version => { + const { default: sentryModule } = await import('../src/module'); + const nuxt = { + _version: version, + options: { dev: true, alias: {}, buildDir: '/app/.nuxt' }, + hook: vi.fn(), + hooks: { hook: vi.fn() }, + } as unknown as Nuxt; + + await (sentryModule as unknown as { setup: (options: object, nuxt: Nuxt) => Promise }).setup({}, nuxt); + + expect(nuxt.options.alias).toEqual({}); + }); +}); From 12988e99c63e00af9a923feecdc02cf747dc04b1 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Fri, 9 Oct 2026 12:30:00 +0200 Subject: [PATCH 3/3] test(nuxt): Remove module alias test The test mocks most of module setup just to cover a deleted code path. Co-Authored-By: Claude Opus 5.5 --- packages/nuxt/test/module.test.ts | 40 ------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 packages/nuxt/test/module.test.ts diff --git a/packages/nuxt/test/module.test.ts b/packages/nuxt/test/module.test.ts deleted file mode 100644 index 99e1a1bd0b2f..000000000000 --- a/packages/nuxt/test/module.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { Nuxt } from '@nuxt/schema'; -import { describe, expect, it, vi } from 'vitest'; -import type * as viteUtils from '../src/vite/utils'; - -vi.mock('@nuxt/kit', () => ({ - addPlugin: vi.fn(), - addPluginTemplate: vi.fn(), - addTemplate: vi.fn(), - addVitePlugin: vi.fn(), - createResolver: vi.fn(() => ({ resolve: (input: string) => input })), - defineNuxtModule: (definition: unknown) => definition, -})); - -vi.mock('../src/vite/utils', async importOriginal => ({ - ...(await importOriginal()), - resolveServerApi: vi.fn(() => 'nitropack'), - findDefaultSdkInitFile: vi.fn((type: string) => `/app/sentry.${type}.config.ts`), -})); - -vi.mock('../src/vite/nitroServer', () => ({ setupNitroServer: vi.fn() })); -vi.mock('../src/vite/orchestrion', () => ({ setupOrchestrion: vi.fn() })); -vi.mock('../src/vite/sourceMaps', () => ({ setupSourceMaps: vi.fn() })); - -describe('Sentry Nuxt module', () => { - // Nuxt writes every alias into the `paths` of the generated `.nuxt/tsconfig.*.json` files, - // where vue-tsc rejects bare specifiers (TS5090) (https://github.com/getsentry/sentry-javascript/issues/25188) - it.each(['3.17.0', '4.5.2'])('does not add Nuxt aliases in dev mode (Nuxt %s)', async version => { - const { default: sentryModule } = await import('../src/module'); - const nuxt = { - _version: version, - options: { dev: true, alias: {}, buildDir: '/app/.nuxt' }, - hook: vi.fn(), - hooks: { hook: vi.fn() }, - } as unknown as Nuxt; - - await (sentryModule as unknown as { setup: (options: object, nuxt: Nuxt) => Promise }).setup({}, nuxt); - - expect(nuxt.options.alias).toEqual({}); - }); -});