@electron-forge/core
Version:
A complete tool for building modern Electron applications
58 lines (50 loc) • 2.01 kB
text/typescript
import path from 'path';
import debug from 'debug';
const d = debug('electron-forge:require-search');
// https://github.com/nodejs/node/blob/da0ede1ad55a502a25b4139f58aab3fb1ee3bf3f/lib/internal/modules/cjs/loader.js#L353-L359
type RequireError = Error & {
code: string;
path: string;
requestPath: string | undefined;
};
export function requireSearchRaw<T>(relativeTo: string, paths: string[]): T | null {
// Attempt to locally short-circuit if we're running from a checkout of forge
if (__dirname.includes('forge/packages/api/core/') && paths.length === 1 && paths[0].startsWith('@electron-forge/')) {
const [moduleType, moduleName] = paths[0].split('/')[1].split('-');
try {
const localPath = path.resolve(__dirname, '..', '..', '..', '..', moduleType, moduleName);
d('testing local forge build', { moduleType, moduleName, localPath });
return require(localPath);
} catch {
// Ignore
}
}
// Load via normal search paths
const testPaths = paths
.concat(paths.map((mapPath) => path.resolve(relativeTo, mapPath)))
.concat(paths.map((mapPath) => path.resolve(relativeTo, 'node_modules', mapPath)));
d('searching', testPaths, 'relative to', relativeTo);
for (const testPath of testPaths) {
try {
d('testing', testPath);
return require(testPath);
} catch (err) {
if (err instanceof Error) {
const requireErr = err as RequireError;
// Ignore require-related errors
if (requireErr.code !== 'MODULE_NOT_FOUND' || ![undefined, testPath].includes(requireErr.requestPath)) {
throw err;
}
}
}
}
d('failed to find a module in', testPaths);
return null;
}
export type PossibleModule<T> = {
default?: T;
} & T;
export default <T>(relativeTo: string, paths: string[]): T | null => {
const result = requireSearchRaw<PossibleModule<T>>(relativeTo, paths);
return typeof result === 'object' && result && result.default ? result.default : (result as T | null);
};