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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
import fs from 'node:fs/promises';
import path from 'node:path';
import type { Alias } from 'vite';
const projectPath = path.resolve(__dirname, '../../../');
const pkgJsonCache = new Map();
// /src/ or \src\, depending on platform
const SRC_DIR_PATH = `${path.sep}src${path.sep}`;
const resolver: Alias = {
find: /^(~\/.+)/,
replacement: '$1',
async customResolver(source, importer) {
let root: null | string = null;
if (importer)
importer = path.normalize(importer);
// source is the path imported on typescript, which always use / as path separator
const [_, sourcePath] = source.split('~/');
const relativeImporter = importer?.replace(projectPath, '');
if (relativeImporter && relativeImporter.includes(SRC_DIR_PATH)) {
const [pkg] = relativeImporter.split(SRC_DIR_PATH);
root = path.join(projectPath, pkg, 'src');
}
else if (importer) {
const pathObj = path.parse(importer);
let parent = pathObj.dir;
while (parent !== pathObj.root) {
parent = path.dirname(parent);
let hasPkgJson = pkgJsonCache.get(parent);
if (hasPkgJson === undefined) {
try {
await fs.stat(path.join(parent, 'package.json'));
pkgJsonCache.set(parent, (hasPkgJson = true));
}
catch {
pkgJsonCache.set(parent, (hasPkgJson = false));
}
}
if (hasPkgJson) {
root = parent;
break;
}
}
if (root === null)
throw new Error(`Failed to resolve import path ${source} in file ${importer}`);
}
else {
throw new Error(`Failed to resolve import path ${source} in file ${importer}`);
}
const absolutePath = path.join(root, sourcePath);
const folderItems = await fs.readdir(path.join(absolutePath, '..'));
// sourcePath is derived from the path imported on typescript, which always use / as path separator
const item = folderItems.find(i => i.startsWith(sourcePath.split('/').at(-1)!))!;
const fullPath = absolutePath + path.extname(item);
const stats = await fs.stat(fullPath);
if (stats.isDirectory()) {
const directoryItems = await fs.readdir(absolutePath + path.extname(item));
const indexFile = directoryItems.find(i => i.startsWith('index'));
if (!indexFile)
throw new Error(`Failed to resolve import path ${source} in file ${importer}`);
return path.join(absolutePath, indexFile);
}
else {
return fullPath;
}
},
};
export default resolver;
|