fix: handle var declaration for `createRequire` (#19804)

This commit is contained in:
Gengkun 2025-08-14 21:40:07 +08:00 committed by GitHub
parent c21b4e2475
commit 0d7aaae4ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 128 additions and 34 deletions

View File

@ -1955,6 +1955,32 @@ class JavascriptParser extends Parser {
}
}
/**
* Module pre walking iterates the scope for import entries
* @param {(Statement | ModuleDeclaration)[]} statements statements
*/
modulePreWalkStatements(statements) {
for (let index = 0, len = statements.length; index < len; index++) {
const statement = statements[index];
/** @type {StatementPath} */
(this.statementPath).push(statement);
switch (statement.type) {
case "ImportDeclaration":
this.modulePreWalkImportDeclaration(statement);
break;
case "ExportAllDeclaration":
this.modulePreWalkExportAllDeclaration(statement);
break;
case "ExportNamedDeclaration":
this.modulePreWalkExportNamedDeclaration(statement);
break;
}
this.prevStatement =
/** @type {StatementPath} */
(this.statementPath).pop();
}
}
/**
* Pre walking iterates the scope for variable declarations
* @param {(Statement | ModuleDeclaration)[]} statements statements
@ -2075,12 +2101,6 @@ class JavascriptParser extends Parser {
return;
}
switch (statement.type) {
case "ImportDeclaration":
this.blockPreWalkImportDeclaration(statement);
break;
case "ExportAllDeclaration":
this.blockPreWalkExportAllDeclaration(statement);
break;
case "ExportDefaultDeclaration":
this.blockPreWalkExportDefaultDeclaration(statement);
break;
@ -2620,7 +2640,7 @@ class JavascriptParser extends Parser {
/**
* @param {ImportDeclaration} statement statement
*/
blockPreWalkImportDeclaration(statement) {
modulePreWalkImportDeclaration(statement) {
const source = /** @type {ImportSource} */ (statement.source.value);
this.hooks.import.call(statement, source);
for (const specifier of statement.specifiers) {
@ -2690,14 +2710,49 @@ class JavascriptParser extends Parser {
/**
* @param {ExportNamedDeclaration} statement statement
*/
blockPreWalkExportNamedDeclaration(statement) {
let source;
if (statement.source) {
source = /** @type {ImportSource} */ (statement.source.value);
this.hooks.exportImport.call(statement, source);
} else {
this.hooks.export.call(statement);
modulePreWalkExportNamedDeclaration(statement) {
if (!statement.source) return;
const source = /** @type {ImportSource} */ (statement.source.value);
this.hooks.exportImport.call(statement, source);
if (statement.specifiers) {
for (
let specifierIndex = 0;
specifierIndex < statement.specifiers.length;
specifierIndex++
) {
const specifier = statement.specifiers[specifierIndex];
switch (specifier.type) {
case "ExportSpecifier": {
const localName =
/** @type {Identifier} */ (specifier.local).name ||
/** @type {string} */ (
/** @type {Literal} */ (specifier.local).value
);
const name =
/** @type {Identifier} */
(specifier.exported).name ||
/** @type {string} */
(/** @type {Literal} */ (specifier.exported).value);
this.hooks.exportImportSpecifier.call(
statement,
source,
localName,
name,
specifierIndex
);
break;
}
}
}
}
}
/**
* @param {ExportNamedDeclaration} statement statement
*/
blockPreWalkExportNamedDeclaration(statement) {
if (statement.source) return;
this.hooks.export.call(statement);
if (
statement.declaration &&
!this.hooks.exportDeclaration.call(statement, statement.declaration)
@ -2730,22 +2785,12 @@ class JavascriptParser extends Parser {
(specifier.exported).name ||
/** @type {string} */
(/** @type {Literal} */ (specifier.exported).value);
if (source) {
this.hooks.exportImportSpecifier.call(
statement,
source,
localName,
name,
specifierIndex
);
} else {
this.hooks.exportSpecifier.call(
statement,
localName,
name,
specifierIndex
);
}
this.hooks.exportSpecifier.call(
statement,
localName,
name,
specifierIndex
);
break;
}
}
@ -2837,7 +2882,7 @@ class JavascriptParser extends Parser {
/**
* @param {ExportAllDeclaration} statement statement
*/
blockPreWalkExportAllDeclaration(statement) {
modulePreWalkExportAllDeclaration(statement) {
const source = /** @type {ImportSource} */ (statement.source.value);
const name = statement.exported
? /** @type {Identifier} */
@ -4568,6 +4613,7 @@ class JavascriptParser extends Parser {
if (this.hooks.program.call(ast, comments) === undefined) {
this.destructuringAssignmentProperties = new WeakMap();
this.detectMode(ast.body);
this.modulePreWalkStatements(ast.body);
this.preWalkStatements(ast.body);
this.prevStatement = undefined;
this.blockPreWalkStatements(ast.body);

View File

@ -1,6 +1,10 @@
import { createRequire as _createRequire } from "module";
import { createRequire as __createRequire, builtinModules } from "module";
import { createRequire as ___createRequire} from "node:module";
import { createRequire as ___createRequire } from "node:module";
let topLetRequire = _createRequireForVar(import.meta.url);
var topVarRequire = _createRequireForVar(import.meta.url);
import { createRequire as _createRequireForVar } from "node:module";
it("should evaluate require/createRequire", () => {
expect(
@ -73,3 +77,10 @@ it("should add warning on using require.main", () => {
it("should import Node.js module", () => {
expect(Array.isArray(builtinModules)).toBe(true);
});
var varRequire = _createRequireForVar(import.meta.url);
it("should works with top-level var declarations", () => {
expect(varRequire("./a")).toBe(1);
expect(topVarRequire("./b")).toBe(2);
expect(topLetRequire("./c")).toBe(3);
});

41
types.d.ts vendored
View File

@ -7056,6 +7056,40 @@ declare class JavascriptParser extends ParserClass {
classy: ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration
): void;
/**
* Module pre walking iterates the scope for import entries
*/
modulePreWalkStatements(
statements: (
| ImportDeclarationJavascriptParser
| ExportNamedDeclarationJavascriptParser
| ExportAllDeclarationJavascriptParser
| FunctionDeclaration
| VariableDeclaration
| ClassDeclaration
| ExpressionStatement
| BlockStatement
| StaticBlock
| EmptyStatement
| DebuggerStatement
| WithStatement
| ReturnStatement
| LabeledStatement
| BreakStatement
| ContinueStatement
| IfStatement
| SwitchStatement
| ThrowStatement
| TryStatement
| WhileStatement
| DoWhileStatement
| ForStatement
| ForInStatement
| ForOfStatement
| ExportDefaultDeclaration
)[]
): void;
/**
* Pre walking iterates the scope for variable declarations
*/
@ -7295,13 +7329,16 @@ declare class JavascriptParser extends ParserClass {
): void;
blockPreWalkExpressionStatement(statement: ExpressionStatement): void;
preWalkAssignmentExpression(expression: AssignmentExpression): void;
blockPreWalkImportDeclaration(
modulePreWalkImportDeclaration(
statement: ImportDeclarationJavascriptParser
): void;
enterDeclaration(
declaration: Declaration,
onIdent: (ident: string, identifier: Identifier) => void
): void;
modulePreWalkExportNamedDeclaration(
statement: ExportNamedDeclarationJavascriptParser
): void;
blockPreWalkExportNamedDeclaration(
statement: ExportNamedDeclarationJavascriptParser
): void;
@ -7312,7 +7349,7 @@ declare class JavascriptParser extends ParserClass {
statement: ExportDefaultDeclaration
): void;
walkExportDefaultDeclaration(statement: ExportDefaultDeclaration): void;
blockPreWalkExportAllDeclaration(
modulePreWalkExportAllDeclaration(
statement: ExportAllDeclarationJavascriptParser
): void;
preWalkVariableDeclaration(statement: VariableDeclaration): void;