forked from electron-userland/electron-builder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprojectModuleResolver.ts
More file actions
80 lines (73 loc) · 2.59 KB
/
projectModuleResolver.ts
File metadata and controls
80 lines (73 loc) · 2.59 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
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
import { log } from "builder-util"
import * as path from "path"
import * as fs from "fs"
export interface ResolveFromProjectOptions {
/** The project directory to resolve from */
projectDir: string
/** Module specifier (e.g., "electron-webpack/out/electron-builder.js") */
moduleSpecifier: string
/** If true, returns null instead of throwing when module not found */
optional?: boolean
}
/**
* Resolves a module from the user's project directory context.
* This is necessary for pnpm compatibility where modules can only
* require their direct dependencies.
*
* @param options Resolution options
* @returns The resolved module path, or null if optional and not found
* @throws Error if module not found and not optional
*/
export function resolveFromProject(options: ResolveFromProjectOptions): string | null {
const { projectDir, moduleSpecifier, optional = false } = options
// Build the paths array for resolution
// Start from project's node_modules and walk up
const searchPaths: string[] = []
let currentDir = projectDir
const root = path.parse(currentDir).root
while (currentDir !== root) {
const nodeModulesPath = path.join(currentDir, "node_modules")
if (fs.existsSync(nodeModulesPath)) {
searchPaths.push(currentDir)
}
const parentDir = path.dirname(currentDir)
if (parentDir === currentDir) break
currentDir = parentDir
}
// If no paths found, at least try the project directory
if (searchPaths.length === 0) {
searchPaths.push(projectDir)
}
try {
const resolved = require.resolve(moduleSpecifier, { paths: searchPaths })
log.debug({ moduleSpecifier, resolved }, "resolved module from project context")
return resolved
} catch (error: any) {
if (optional) {
log.debug({ moduleSpecifier, projectDir, error: error.message }, "optional module not found in project")
return null
}
throw new Error(
`Cannot resolve module "${moduleSpecifier}" from project directory "${projectDir}". ` +
`This module must be installed in your project. ` +
`If you're using pnpm, ensure the module is listed in your dependencies. ` +
`Original error: ${error.message}`
)
}
}
/**
* Checks if a module exists in the user's project context.
*
* @param projectDir The project directory
* @param moduleSpecifier The module to check for
* @returns true if the module can be resolved
*/
export function moduleExistsInProject(projectDir: string, moduleSpecifier: string): boolean {
return (
resolveFromProject({
projectDir,
moduleSpecifier,
optional: true,
}) !== null
)
}