Skip to content

Commit 9659275

Browse files
authored
feat(nuxt): Add alias for @opentelemetry/resources (#16727)
Under certain circumstances, you'll get a "Cannot find module" error in Nuxt dev mode. This is because ESM requires the .js file extensions to make the imports work and there is a tracking issue in OTel to support the ESM spec (which also means adding the file extensions): open-telemetry/opentelemetry-js#4898 Fixes #15204 As the issue is very long, here are some relevant comments: - [ESM and OTel explanation](#15204 (comment)) - [Potential Workarounds](#15204 (comment))
1 parent 5f7129c commit 9659275

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

packages/nuxt/src/module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as path from 'path';
44
import type { SentryNuxtModuleOptions } from './common/types';
55
import { addDynamicImportEntryFileWrapper, addSentryTopImport, addServerConfigToBuild } from './vite/addServerConfig';
66
import { setupSourceMaps } from './vite/sourceMaps';
7-
import { findDefaultSdkInitFile } from './vite/utils';
7+
import { addOTelCommonJSImportAlias, findDefaultSdkInitFile } from './vite/utils';
88

99
export type ModuleOptions = SentryNuxtModuleOptions;
1010

@@ -69,6 +69,8 @@ export default defineNuxtModule<ModuleOptions>({
6969
setupSourceMaps(moduleOptions, nuxt);
7070
}
7171

72+
addOTelCommonJSImportAlias(nuxt);
73+
7274
nuxt.hooks.hook('nitro:init', nitro => {
7375
if (serverConfigFile?.includes('.server.config')) {
7476
if (nitro.options.dev) {

packages/nuxt/src/vite/utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,21 @@ export function constructFunctionReExport(pathWithQuery: string, entryId: string
179179
),
180180
);
181181
}
182+
183+
/**
184+
* Sets up alias to work around OpenTelemetry's incomplete ESM imports.
185+
* https://github.com/getsentry/sentry-javascript/issues/15204
186+
*
187+
* OpenTelemetry's @opentelemetry/resources package has incomplete imports missing
188+
* the .js file extensions (like execAsync for machine-id detection). This causes module resolution
189+
* errors in certain Nuxt configurations, particularly when local Nuxt modules in Nuxt 4 are present.
190+
*
191+
* @see https://nuxt.com/docs/guide/concepts/esm#aliasing-libraries
192+
*/
193+
export function addOTelCommonJSImportAlias(nuxt: Nuxt): void {
194+
if (!nuxt.options.alias) {
195+
nuxt.options.alias = {};
196+
}
197+
198+
nuxt.options.alias['@opentelemetry/resources'] = '@opentelemetry/resources/build/src/index.js';
199+
}

packages/nuxt/test/vite/utils.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as fs from 'fs';
22
import type { Nuxt } from 'nuxt/schema';
33
import { afterEach, describe, expect, it, vi } from 'vitest';
44
import {
5+
addOTelCommonJSImportAlias,
56
constructFunctionReExport,
67
constructWrappedFunctionExportQuery,
78
extractFunctionReexportQueryParameters,
@@ -366,3 +367,50 @@ export { foo_sentryWrapped as foo };
366367
expect(result).toBe('');
367368
});
368369
});
370+
371+
describe('addOTelCommonJSImportAlias', () => {
372+
it('adds alias for @opentelemetry/resources when options.alias does not exist', () => {
373+
const nuxtMock: Nuxt = {
374+
options: {},
375+
} as unknown as Nuxt;
376+
377+
addOTelCommonJSImportAlias(nuxtMock);
378+
379+
expect(nuxtMock.options.alias).toEqual({
380+
'@opentelemetry/resources': '@opentelemetry/resources/build/src/index.js',
381+
});
382+
});
383+
384+
it('adds alias for @opentelemetry/resources when options.alias already exists', () => {
385+
const nuxtMock: Nuxt = {
386+
options: {
387+
alias: {
388+
'existing-alias': 'some-path',
389+
},
390+
},
391+
} as unknown as Nuxt;
392+
393+
addOTelCommonJSImportAlias(nuxtMock);
394+
395+
expect(nuxtMock.options.alias).toEqual({
396+
'existing-alias': 'some-path',
397+
'@opentelemetry/resources': '@opentelemetry/resources/build/src/index.js',
398+
});
399+
});
400+
401+
it('overwrites existing alias for @opentelemetry/resources if already present', () => {
402+
const nuxtMock: Nuxt = {
403+
options: {
404+
alias: {
405+
'@opentelemetry/resources': 'some-other-path',
406+
},
407+
},
408+
} as unknown as Nuxt;
409+
410+
addOTelCommonJSImportAlias(nuxtMock);
411+
412+
expect(nuxtMock.options.alias).toEqual({
413+
'@opentelemetry/resources': '@opentelemetry/resources/build/src/index.js',
414+
});
415+
});
416+
});

0 commit comments

Comments
 (0)