/
resolve-module-sync.ts
138 lines (118 loc) · 4.52 KB
/
resolve-module-sync.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
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import type * as d from '../../../declarations';
import { COMMON_DIR_FILENAMES, getCommonDirName, isCommonDirModuleFile, shouldFetchModule } from './resolve-utils';
import { fetchModuleSync } from '../fetch/fetch-module-sync';
import { getCommonDirUrl, getNodeModuleFetchUrl, packageVersions } from '../fetch/fetch-utils';
import { isString, normalizeFsPath, normalizePath } from '@utils';
import { IS_WEB_WORKER_ENV } from '../environment';
import { basename, dirname } from 'path';
import resolve, { SyncOpts } from 'resolve';
export const resolveRemoteModuleIdSync = (config: d.Config, inMemoryFs: d.InMemoryFileSystem, opts: d.ResolveModuleIdOptions) => {
const packageJson = resolveRemotePackageJsonSync(config, inMemoryFs, opts.moduleId);
if (packageJson) {
const resolveModuleSyncOpts: d.ResolveModuleIdOptions = {
...opts,
exts: ['.js', '.mjs'],
};
const resolvedUrl = resolveModuleIdSync(config.sys, inMemoryFs, resolveModuleSyncOpts);
if (typeof resolvedUrl === 'string') {
return {
resolvedUrl,
packageJson,
};
}
}
return null;
};
const resolveRemotePackageJsonSync = (config: d.Config, inMemoryFs: d.InMemoryFileSystem, moduleId: string) => {
if (inMemoryFs) {
const filePath = normalizePath(config.sys.getLocalModulePath({ rootDir: config.rootDir, moduleId, path: 'package.json' }));
let pkgJson = inMemoryFs.readFileSync(filePath);
if (!isString(pkgJson) && IS_WEB_WORKER_ENV) {
const url = config.sys.getRemoteModuleUrl({ moduleId, path: 'package.json' });
pkgJson = fetchModuleSync(config.sys, inMemoryFs, packageVersions, url, filePath);
}
if (typeof pkgJson === 'string') {
try {
return JSON.parse(pkgJson) as d.PackageJsonData;
} catch (e) {}
}
}
return null;
};
export const resolveModuleIdSync = (sys: d.CompilerSystem, inMemoryFs: d.InMemoryFileSystem, opts: d.ResolveModuleIdOptions) => {
if (inMemoryFs) {
const resolverOpts = createCustomResolverSync(sys, inMemoryFs, opts.exts);
resolverOpts.basedir = dirname(opts.containingFile);
resolverOpts.packageFilter = opts.packageFilter;
const resolvedModule = resolve.sync(opts.moduleId, resolverOpts);
return resolvedModule;
}
return null;
};
export const createCustomResolverSync = (sys: d.CompilerSystem, inMemoryFs: d.InMemoryFileSystem, exts: string[]): SyncOpts => {
return {
isFile(filePath: string) {
const fsFilePath = normalizeFsPath(filePath);
const stat = inMemoryFs.statSync(fsFilePath);
if (stat.isFile) {
return true;
}
if (shouldFetchModule(fsFilePath)) {
const endsWithExt = exts.some(ext => fsFilePath.endsWith(ext));
if (!endsWithExt) {
return false;
}
const url = getNodeModuleFetchUrl(sys, packageVersions, fsFilePath);
const content = fetchModuleSync(sys, inMemoryFs, packageVersions, url, fsFilePath);
return typeof content === 'string';
}
return false;
},
isDirectory(dirPath: string) {
const fsDirPath = normalizeFsPath(dirPath);
const stat = inMemoryFs.statSync(fsDirPath);
if (stat.isDirectory) {
return true;
}
if (shouldFetchModule(fsDirPath)) {
if (basename(fsDirPath) === 'node_modules') {
// just the /node_modules directory
inMemoryFs.sys.createDirSync(fsDirPath);
inMemoryFs.clearFileCache(fsDirPath);
return true;
}
if (isCommonDirModuleFile(fsDirPath)) {
// don't bother seeing if it's a directory if it has a common file extension
return false;
}
const checkFileExists = (fileName: string) => {
const url = getCommonDirUrl(sys, packageVersions, fsDirPath, fileName);
const filePath = getCommonDirName(fsDirPath, fileName);
const content = fetchModuleSync(sys, inMemoryFs, packageVersions, url, filePath);
return isString(content);
};
return COMMON_DIR_FILENAMES.some(checkFileExists);
}
return false;
},
readFileSync(p: string) {
const data = inMemoryFs.readFileSync(p);
if (isString(data)) {
return data;
}
throw new Error(`file not found: ${p}`);
},
realpathSync(p: string) {
const fsFilePath = normalizeFsPath(p);
try {
return sys.realpathSync(fsFilePath);
} catch (realpathErr) {
if (realpathErr.code !== 'ENOENT') {
throw realpathErr;
}
}
return fsFilePath;
},
extensions: exts,
} as any;
};