Skip to content

Commit 7ef76de

Browse files
timfishanonrig
authored andcommitted
fix(node): Correctly resolve module name (#10001)
1 parent 91ae9cb commit 7ef76de

File tree

2 files changed

+52
-45
lines changed

2 files changed

+52
-45
lines changed

packages/node/src/module.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { posix, sep } from 'path';
2-
3-
const isWindowsPlatform = sep === '\\';
2+
import { dirname } from '@sentry/utils';
43

54
/** normalizes Windows paths */
65
function normalizeWindowsPath(path: string): string {
@@ -9,52 +8,62 @@ function normalizeWindowsPath(path: string): string {
98
.replace(/\\/g, '/'); // replace all `\` instances with `/`
109
}
1110

11+
// We cache this so we don't have to recompute it
12+
let basePath: string | undefined;
13+
14+
function getBasePath(): string {
15+
if (!basePath) {
16+
const baseDir =
17+
require && require.main && require.main.filename ? dirname(require.main.filename) : global.process.cwd();
18+
basePath = `${baseDir}/`;
19+
}
20+
21+
return basePath;
22+
}
23+
1224
/** Gets the module from a filename */
1325
export function getModuleFromFilename(
1426
filename: string | undefined,
15-
normalizeWindowsPathSeparator: boolean = isWindowsPlatform,
27+
basePath: string = getBasePath(),
28+
isWindows: boolean = sep === '\\',
1629
): string | undefined {
1730
if (!filename) {
1831
return;
1932
}
2033

21-
const normalizedFilename = normalizeWindowsPathSeparator ? normalizeWindowsPath(filename) : filename;
34+
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
35+
const normalizedFilename = isWindows ? normalizeWindowsPath(filename) : filename;
2236

2337
// eslint-disable-next-line prefer-const
24-
let { root, dir, base: basename, ext } = posix.parse(normalizedFilename);
25-
26-
const base = (require && require.main && require.main.filename && dir) || global.process.cwd();
27-
28-
const normalizedBase = `${base}/`;
29-
30-
// It's specifically a module
31-
let file = basename;
38+
let { dir, base: file, ext } = posix.parse(normalizedFilename);
3239

3340
if (ext === '.js' || ext === '.mjs' || ext === '.cjs') {
3441
file = file.slice(0, ext.length * -1);
3542
}
3643

37-
if (!root && !dir) {
44+
if (!dir) {
3845
// No dirname whatsoever
3946
dir = '.';
4047
}
4148

42-
let n = dir.lastIndexOf('/node_modules/');
49+
let n = dir.lastIndexOf('/node_modules');
4350
if (n > -1) {
44-
// /node_modules/ is 14 chars
4551
return `${dir.slice(n + 14).replace(/\//g, '.')}:${file}`;
4652
}
53+
4754
// Let's see if it's a part of the main module
4855
// To be a part of main module, it has to share the same base
4956
n = `${dir}/`.lastIndexOf(normalizedBase, 0);
50-
5157
if (n === 0) {
5258
let moduleName = dir.slice(normalizedBase.length).replace(/\//g, '.');
59+
5360
if (moduleName) {
5461
moduleName += ':';
5562
}
5663
moduleName += file;
64+
5765
return moduleName;
5866
}
67+
5968
return file;
6069
}

packages/node/test/module.test.ts

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,40 @@
11
import { getModuleFromFilename } from '../src/module';
22

3-
function withFilename(fn: () => void, filename: string) {
4-
const prevFilename = require.main?.filename;
5-
if (require.main?.filename) {
6-
require.main.filename = filename;
7-
}
8-
9-
try {
10-
fn();
11-
} finally {
12-
if (require.main && prevFilename) {
13-
require.main.filename = prevFilename;
14-
}
15-
}
16-
}
17-
183
describe('getModuleFromFilename', () => {
194
test('Windows', () => {
20-
withFilename(() => {
21-
expect(getModuleFromFilename('C:\\Users\\users\\Tim\\Desktop\\node_modules\\module.js', true)).toEqual('module');
22-
}, 'C:\\Users\\Tim\\app.js');
5+
expect(
6+
getModuleFromFilename('C:\\Users\\Tim\\node_modules\\some-dep\\module.js', 'C:\\Users\\Tim\\', true),
7+
).toEqual('some-dep:module');
8+
9+
expect(getModuleFromFilename('C:\\Users\\Tim\\some\\more\\feature.js', 'C:\\Users\\Tim\\', true)).toEqual(
10+
'some.more:feature',
11+
);
2312
});
2413

2514
test('POSIX', () => {
26-
withFilename(() => {
27-
expect(getModuleFromFilename('/Users/users/Tim/Desktop/node_modules/module.js')).toEqual('module');
28-
}, '/Users/Tim/app.js');
15+
expect(getModuleFromFilename('/Users/Tim/node_modules/some-dep/module.js', '/Users/Tim/')).toEqual(
16+
'some-dep:module',
17+
);
18+
19+
expect(getModuleFromFilename('/Users/Tim/some/more/feature.js', '/Users/Tim/')).toEqual('some.more:feature');
20+
expect(getModuleFromFilename('/Users/Tim/main.js', '/Users/Tim/')).toEqual('main');
21+
});
22+
23+
test('.mjs', () => {
24+
expect(getModuleFromFilename('/Users/Tim/node_modules/some-dep/module.mjs', '/Users/Tim/')).toEqual(
25+
'some-dep:module',
26+
);
2927
});
3028

31-
test('POSIX .mjs', () => {
32-
withFilename(() => {
33-
expect(getModuleFromFilename('/Users/users/Tim/Desktop/node_modules/module.mjs')).toEqual('module');
34-
}, '/Users/Tim/app.js');
29+
test('.cjs', () => {
30+
expect(getModuleFromFilename('/Users/Tim/node_modules/some-dep/module.cjs', '/Users/Tim/')).toEqual(
31+
'some-dep:module',
32+
);
3533
});
3634

37-
test('POSIX .cjs', () => {
38-
withFilename(() => {
39-
expect(getModuleFromFilename('/Users/users/Tim/Desktop/node_modules/module.cjs')).toEqual('module');
40-
}, '/Users/Tim/app.js');
35+
test('node internal', () => {
36+
expect(getModuleFromFilename('node.js', '/Users/Tim/')).toEqual('node');
37+
expect(getModuleFromFilename('node:internal/process/task_queues', '/Users/Tim/')).toEqual('task_queues');
38+
expect(getModuleFromFilename('node:internal/timers', '/Users/Tim/')).toEqual('timers');
4139
});
4240
});

0 commit comments

Comments
 (0)