-
Notifications
You must be signed in to change notification settings - Fork 94
Expand file tree
/
Copy pathModuleProxy.ts
More file actions
39 lines (34 loc) · 1.52 KB
/
ModuleProxy.ts
File metadata and controls
39 lines (34 loc) · 1.52 KB
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
type ImportType = ReturnType<typeof require>;
/**
* Create a lazily-imported module proxy.
* This is useful for lazily requiring optional dependencies.
*/
const createModuleProxy = <TModule>(getModule: () => ImportType): TModule => {
const holder: {module: TModule | undefined} = {module: undefined};
const proxy = new Proxy(holder, {
get: (target, property) => {
if (property === '$$typeof') {
// If inlineRequires is enabled, Metro will look up all imports
// with the $$typeof operator. In this case, this will throw the
// `OptionalDependencyNotInstalledError` error because we try to access the module
// even though we are not using it (Metro does it), so instead we return undefined
// to bail out of inlineRequires here.
return undefined;
}
if (target.module == null) {
// lazy initialize module via require()
// caller needs to make sure the require() call is wrapped in a try/catch
// eslint-disable-next-line no-param-reassign
target.module = getModule() as TModule;
}
return target.module[property as keyof typeof holder.module];
},
});
return proxy as unknown as TModule;
};
class OptionalDependencyNotInstalledError extends Error {
constructor(name: string) {
super(`${name} is not installed!`);
}
}
export {createModuleProxy, OptionalDependencyNotInstalledError};