mirror of
https://github.com/morluto/rea
synced 2026-10-26 22:28:27 -04:00
fix(javascript): keep paths after __dirname inside the source directory (#2366)
Node's path.join does not reset at an absolute segment, so path.join(__dirname, '/preload.js') is <dir>/preload.js. The static path projection skipped the __dirname anchor and joined the remaining parts, which turned that common spelling into the root path /preload.js. In an app whose main script lives in src/, the BrowserWindow preload was then reported not-found, or resolved to an unrelated preload.js at the artifact root, and the utilityProcess.fork target was never resolved. String concatenation had the same defect: path.dirname(__filename) + '/preload.js' projected to /preload.js, and __dirname + '/preload.js' stayed unknown. A source directory now contributes "." to a join, so path.join(__dirname) projects to "." like path.resolve(__dirname). A concatenation that starts with __dirname or the source file's dirname keeps text that begins with a separator inside that directory; other text extends the directory's own name and stays unknown. The empty-string projection of path.dirname(__filename), which produced the wrong concatenation, is removed, so a bare path.dirname(__filename) is unknown like a bare __dirname.
This commit is contained in:
@@ -181,18 +181,37 @@ export const staticPath = (node: t.Node): string | undefined => {
|
||||
if (t.isStringLiteral(node)) return node.value;
|
||||
if (t.isTemplateLiteral(node) && node.expressions.length === 0)
|
||||
return stringValue(node);
|
||||
if (t.isBinaryExpression(node, { operator: "+" })) {
|
||||
const left = staticPath(node.left);
|
||||
const right = staticPath(node.right);
|
||||
return left === undefined || right === undefined
|
||||
? undefined
|
||||
: `${left}${right}`;
|
||||
}
|
||||
if (t.isBinaryExpression(node, { operator: "+" }))
|
||||
return staticConcatenation(node);
|
||||
if (t.isCallExpression(node) || t.isNewExpression(node))
|
||||
return staticCallPath(node);
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Concatenate inert text. A leading source directory contributes no text:
|
||||
* `__dirname + "/preload.js"` names a file inside it, while text without a
|
||||
* leading separator extends the directory's own name and stays unknown.
|
||||
*/
|
||||
const staticConcatenation = (node: t.BinaryExpression): string | undefined => {
|
||||
const operands: t.Node[] = [];
|
||||
let current: t.Node = node;
|
||||
while (t.isBinaryExpression(current, { operator: "+" })) {
|
||||
operands.push(current.right);
|
||||
current = current.left;
|
||||
}
|
||||
const anchored = isDirectoryPath(current);
|
||||
if (!anchored) operands.push(current);
|
||||
let text = "";
|
||||
for (const operand of operands.reverse()) {
|
||||
const value = staticPath(operand);
|
||||
if (value === undefined) return undefined;
|
||||
text += value;
|
||||
}
|
||||
if (!anchored) return text;
|
||||
return text.startsWith("/") ? posix.join(".", text) : undefined;
|
||||
};
|
||||
|
||||
const staticCallPath = (
|
||||
node: t.CallExpression | t.NewExpression,
|
||||
): string | undefined => {
|
||||
@@ -204,11 +223,6 @@ const staticCallPath = (
|
||||
if (name === "fileURLToPath" || name.endsWith(".fileURLToPath")) {
|
||||
return staticFileUrlPath(argumentNode(node.arguments[0]));
|
||||
}
|
||||
if (
|
||||
(name === "dirname" || name.endsWith(".dirname")) &&
|
||||
isFileIdentity(argumentNode(node.arguments[0]))
|
||||
)
|
||||
return "";
|
||||
if (name.endsWith(".resolve"))
|
||||
return name === "win32.resolve" || name.endsWith(".win32.resolve")
|
||||
? undefined
|
||||
@@ -216,7 +230,12 @@ const staticCallPath = (
|
||||
if (!name.endsWith(".join") && name !== "join") return undefined;
|
||||
const parts: string[] = [];
|
||||
for (const argument of node.arguments) {
|
||||
if (isDirectoryIdentity(argumentNode(argument))) continue;
|
||||
if (isDirectoryIdentity(argumentNode(argument))) {
|
||||
// join never resets at an absolute segment, so `/preload.js` after the
|
||||
// source directory stays inside it.
|
||||
parts.push(".");
|
||||
continue;
|
||||
}
|
||||
const value = t.isNode(argument) ? staticPath(argument) : undefined;
|
||||
if (value === undefined) return undefined;
|
||||
parts.push(value);
|
||||
@@ -331,11 +350,20 @@ const isFilesystemPathExpression = (node: t.Node): boolean => {
|
||||
};
|
||||
|
||||
const isDirectoryIdentity = (node: t.Node | undefined): boolean => {
|
||||
if (t.isIdentifier(node, { name: "__dirname" })) return true;
|
||||
if (isDirectoryPath(node)) return true;
|
||||
if (!t.isCallExpression(node) && !t.isNewExpression(node)) return false;
|
||||
const name = calleeName(node.callee);
|
||||
if (name === "URL" || name.endsWith(".URL"))
|
||||
return isFileIdentity(argumentNode(node.arguments[1]));
|
||||
return (
|
||||
(name === "URL" || name.endsWith(".URL")) &&
|
||||
isFileIdentity(argumentNode(node.arguments[1]))
|
||||
);
|
||||
};
|
||||
|
||||
/** `__dirname` or the dirname of the source file, as a string. */
|
||||
const isDirectoryPath = (node: t.Node | undefined): boolean => {
|
||||
if (t.isIdentifier(node, { name: "__dirname" })) return true;
|
||||
if (!t.isCallExpression(node)) return false;
|
||||
const name = calleeName(node.callee);
|
||||
return (
|
||||
(name === "dirname" || name.endsWith(".dirname")) &&
|
||||
isFileIdentity(argumentNode(node.arguments[0]))
|
||||
|
||||
Reference in New Issue
Block a user