forked from rollup/rollup
-
Notifications
You must be signed in to change notification settings - Fork 0
/
resolveId.ts
60 lines (54 loc) · 1.95 KB
/
resolveId.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { CustomPluginOptions } from '../rollup/types';
import { lstatSync, readdirSync, realpathSync } from './fs';
import { basename, dirname, isAbsolute, resolve } from './path';
import { PluginDriver } from './PluginDriver';
export async function resolveId(
source: string,
importer: string | undefined,
preserveSymlinks: boolean,
pluginDriver: PluginDriver,
skip: number | null,
customOptions: CustomPluginOptions | undefined
) {
const pluginResult = await pluginDriver.hookFirst(
'resolveId',
[source, importer, { custom: customOptions }],
null,
skip
);
if (pluginResult != null) return pluginResult;
// external modules (non-entry modules that start with neither '.' or '/')
// are skipped at this stage.
if (importer !== undefined && !isAbsolute(source) && source[0] !== '.') return null;
// `resolve` processes paths from right to left, prepending them until an
// absolute path is created. Absolute importees therefore shortcircuit the
// resolve call and require no special handing on our part.
// See https://nodejs.org/api/path.html#path_path_resolve_paths
return addJsExtensionIfNecessary(
importer ? resolve(dirname(importer), source) : resolve(source),
preserveSymlinks
);
}
function addJsExtensionIfNecessary(file: string, preserveSymlinks: boolean) {
let found = findFile(file, preserveSymlinks);
if (found) return found;
found = findFile(file + '.mjs', preserveSymlinks);
if (found) return found;
found = findFile(file + '.js', preserveSymlinks);
return found;
}
function findFile(file: string, preserveSymlinks: boolean): string | undefined {
try {
const stats = lstatSync(file);
if (!preserveSymlinks && stats.isSymbolicLink())
return findFile(realpathSync(file), preserveSymlinks);
if ((preserveSymlinks && stats.isSymbolicLink()) || stats.isFile()) {
// check case
const name = basename(file);
const files = readdirSync(dirname(file));
if (files.indexOf(name) !== -1) return file;
}
} catch {
// suppress
}
}