Files
rspade_system/node_modules/webpack/lib/dependencies/CommonJsExportsParserPlugin.js
root f6ac36c632 Enhance refactor commands with controller-aware Route() updates and fix code quality violations
Add semantic token highlighting for 'that' variable and comment file references in VS Code extension
Add Phone_Text_Input and Currency_Input components with formatting utilities
Implement client widgets, form standardization, and soft delete functionality
Add modal scroll lock and update documentation
Implement comprehensive modal system with form integration and validation
Fix modal component instantiation using jQuery plugin API
Implement modal system with responsive sizing, queuing, and validation support
Implement form submission with validation, error handling, and loading states
Implement country/state selectors with dynamic data loading and Bootstrap styling
Revert Rsx::Route() highlighting in Blade/PHP files
Target specific PHP scopes for Rsx::Route() highlighting in Blade
Expand injection selector for Rsx::Route() highlighting
Add custom syntax highlighting for Rsx::Route() and Rsx.Route() calls
Update jqhtml packages to v2.2.165
Add bundle path validation for common mistakes (development mode only)
Create Ajax_Select_Input widget and Rsx_Reference_Data controller
Create Country_Select_Input widget with default country support
Initialize Tom Select on Select_Input widgets
Add Tom Select bundle for enhanced select dropdowns
Implement ISO 3166 geographic data system for country/region selection
Implement widget-based form system with disabled state support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 06:21:56 +00:00

426 lines
14 KiB
JavaScript
Executable File

/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const formatLocation = require("../formatLocation");
const { evaluateToString } = require("../javascript/JavascriptParserHelpers");
const propertyAccess = require("../util/propertyAccess");
const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
const CommonJsExportsDependency = require("./CommonJsExportsDependency");
const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency");
const DynamicExports = require("./DynamicExports");
const HarmonyExports = require("./HarmonyExports");
const ModuleDecoratorDependency = require("./ModuleDecoratorDependency");
/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */
/** @typedef {import("estree").CallExpression} CallExpression */
/** @typedef {import("estree").Expression} Expression */
/** @typedef {import("estree").Super} Super */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
/** @typedef {import("../javascript/JavascriptParser").Members} Members */
/** @typedef {import("../javascript/JavascriptParser").StatementPath} StatementPath */
/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */
/** @typedef {import("../Module").BuildMeta} BuildMeta */
/**
* This function takes a generic expression and detects whether it is an ObjectExpression.
* This is used in the context of parsing CommonJS exports to get the value of the property descriptor
* when the `exports` object is assigned to `Object.defineProperty`.
*
* In CommonJS modules, the `exports` object can be assigned to `Object.defineProperty` and therefore
* webpack has to detect this case and get the value key of the property descriptor. See the following example
* for more information: https://astexplorer.net/#/gist/83ce51a4e96e59d777df315a6d111da6/8058ead48a1bb53c097738225db0967ef7f70e57
*
* This would be an example of a CommonJS module that exports an object with a property descriptor:
* ```js
* Object.defineProperty(exports, "__esModule", { value: true });
* exports.foo = void 0;
* exports.foo = "bar";
* ```
* @param {Expression} expr expression
* @returns {Expression | undefined} returns the value of property descriptor
*/
const getValueOfPropertyDescription = (expr) => {
if (expr.type !== "ObjectExpression") return;
for (const property of expr.properties) {
if (property.type === "SpreadElement" || property.computed) continue;
const key = property.key;
if (key.type !== "Identifier" || key.name !== "value") continue;
return /** @type {Expression} */ (property.value);
}
};
/**
* The purpose of this function is to check whether an expression is a truthy literal or not. This is
* useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy
* values like `null` and `false`. However, exports should only be created if the exported value is truthy.
* @param {Expression} expr expression being checked
* @returns {boolean} true, when the expression is a truthy literal
*/
const isTruthyLiteral = (expr) => {
switch (expr.type) {
case "Literal":
return Boolean(expr.value);
case "UnaryExpression":
if (expr.operator === "!") return isFalsyLiteral(expr.argument);
}
return false;
};
/**
* The purpose of this function is to check whether an expression is a falsy literal or not. This is
* useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy
* values like `null` and `false`. However, exports should only be created if the exported value is truthy.
* @param {Expression} expr expression being checked
* @returns {boolean} true, when the expression is a falsy literal
*/
const isFalsyLiteral = (expr) => {
switch (expr.type) {
case "Literal":
return !expr.value;
case "UnaryExpression":
if (expr.operator === "!") return isTruthyLiteral(expr.argument);
}
return false;
};
/**
* @param {JavascriptParser} parser the parser
* @param {Expression} expr expression
* @returns {{ argument: BasicEvaluatedExpression, ids: ExportInfoName[] } | undefined} parsed call
*/
const parseRequireCall = (parser, expr) => {
/** @type {ExportInfoName[]} */
const ids = [];
while (expr.type === "MemberExpression") {
if (expr.object.type === "Super") return;
if (!expr.property) return;
const prop = expr.property;
if (expr.computed) {
if (prop.type !== "Literal") return;
ids.push(`${prop.value}`);
} else {
if (prop.type !== "Identifier") return;
ids.push(prop.name);
}
expr = expr.object;
}
if (expr.type !== "CallExpression" || expr.arguments.length !== 1) return;
const callee = expr.callee;
if (
callee.type !== "Identifier" ||
parser.getVariableInfo(callee.name) !== "require"
) {
return;
}
const arg = expr.arguments[0];
if (arg.type === "SpreadElement") return;
const argValue = parser.evaluateExpression(arg);
return { argument: argValue, ids: ids.reverse() };
};
const PLUGIN_NAME = "CommonJsExportsParserPlugin";
class CommonJsExportsParserPlugin {
/**
* @param {ModuleGraph} moduleGraph module graph
*/
constructor(moduleGraph) {
this.moduleGraph = moduleGraph;
}
/**
* @param {JavascriptParser} parser the parser
* @returns {void}
*/
apply(parser) {
const enableStructuredExports = () => {
DynamicExports.enable(parser.state);
};
/**
* @param {boolean} topLevel true, when the export is on top level
* @param {Members} members members of the export
* @param {Expression | undefined} valueExpr expression for the value
* @returns {void}
*/
const checkNamespace = (topLevel, members, valueExpr) => {
if (!DynamicExports.isEnabled(parser.state)) return;
if (members.length > 0 && members[0] === "__esModule") {
if (valueExpr && isTruthyLiteral(valueExpr) && topLevel) {
DynamicExports.setFlagged(parser.state);
} else {
DynamicExports.setDynamic(parser.state);
}
}
};
/**
* @param {string=} reason reason
*/
const bailout = (reason) => {
DynamicExports.bailout(parser.state);
if (reason) bailoutHint(reason);
};
/**
* @param {string} reason reason
*/
const bailoutHint = (reason) => {
this.moduleGraph
.getOptimizationBailout(parser.state.module)
.push(`CommonJS bailout: ${reason}`);
};
// metadata //
parser.hooks.evaluateTypeof
.for("module")
.tap(PLUGIN_NAME, evaluateToString("object"));
parser.hooks.evaluateTypeof
.for("exports")
.tap(PLUGIN_NAME, evaluateToString("object"));
// exporting //
/**
* @param {AssignmentExpression} expr expression
* @param {CommonJSDependencyBaseKeywords} base commonjs base keywords
* @param {Members} members members of the export
* @returns {boolean | undefined} true, when the expression was handled
*/
const handleAssignExport = (expr, base, members) => {
if (HarmonyExports.isEnabled(parser.state)) return;
// Handle reexporting
const requireCall = parseRequireCall(parser, expr.right);
if (
requireCall &&
requireCall.argument.isString() &&
(members.length === 0 || members[0] !== "__esModule")
) {
enableStructuredExports();
// It's possible to reexport __esModule, so we must convert to a dynamic module
if (members.length === 0) DynamicExports.setDynamic(parser.state);
const dep = new CommonJsExportRequireDependency(
/** @type {Range} */ (expr.range),
null,
base,
members,
/** @type {string} */ (requireCall.argument.string),
requireCall.ids,
!parser.isStatementLevelExpression(expr)
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
dep.optional = Boolean(parser.scope.inTry);
parser.state.module.addDependency(dep);
/** @type {BuildMeta} */ (
parser.state.module.buildMeta
).treatAsCommonJs = true;
return true;
}
if (members.length === 0) return;
enableStructuredExports();
const remainingMembers = members;
checkNamespace(
/** @type {StatementPath} */
(parser.statementPath).length === 1 &&
parser.isStatementLevelExpression(expr),
remainingMembers,
expr.right
);
const dep = new CommonJsExportsDependency(
/** @type {Range} */ (expr.left.range),
null,
base,
remainingMembers
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addDependency(dep);
/** @type {BuildMeta} */ (parser.state.module.buildMeta).treatAsCommonJs =
true;
parser.walkExpression(expr.right);
return true;
};
parser.hooks.assignMemberChain
.for("exports")
.tap(PLUGIN_NAME, (expr, members) =>
handleAssignExport(expr, "exports", members)
);
parser.hooks.assignMemberChain
.for("this")
.tap(PLUGIN_NAME, (expr, members) => {
if (!parser.scope.topLevelScope) return;
return handleAssignExport(expr, "this", members);
});
parser.hooks.assignMemberChain
.for("module")
.tap(PLUGIN_NAME, (expr, members) => {
if (members[0] !== "exports") return;
return handleAssignExport(expr, "module.exports", members.slice(1));
});
parser.hooks.call
.for("Object.defineProperty")
.tap(PLUGIN_NAME, (expression) => {
const expr = /** @type {CallExpression} */ (expression);
if (!parser.isStatementLevelExpression(expr)) return;
if (expr.arguments.length !== 3) return;
if (expr.arguments[0].type === "SpreadElement") return;
if (expr.arguments[1].type === "SpreadElement") return;
if (expr.arguments[2].type === "SpreadElement") return;
const exportsArg = parser.evaluateExpression(expr.arguments[0]);
if (!exportsArg.isIdentifier()) return;
if (
exportsArg.identifier !== "exports" &&
exportsArg.identifier !== "module.exports" &&
(exportsArg.identifier !== "this" || !parser.scope.topLevelScope)
) {
return;
}
const propertyArg = parser.evaluateExpression(expr.arguments[1]);
const property = propertyArg.asString();
if (typeof property !== "string") return;
enableStructuredExports();
const descArg = expr.arguments[2];
checkNamespace(
/** @type {StatementPath} */
(parser.statementPath).length === 1,
[property],
getValueOfPropertyDescription(descArg)
);
const dep = new CommonJsExportsDependency(
/** @type {Range} */ (expr.range),
/** @type {Range} */ (expr.arguments[2].range),
`Object.defineProperty(${exportsArg.identifier})`,
[property]
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addDependency(dep);
/** @type {BuildMeta} */ (
parser.state.module.buildMeta
).treatAsCommonJs = true;
parser.walkExpression(expr.arguments[2]);
return true;
});
// Self reference //
/**
* @param {Expression | Super} expr expression
* @param {CommonJSDependencyBaseKeywords} base commonjs base keywords
* @param {Members} members members of the export
* @param {CallExpression=} call call expression
* @returns {boolean | void} true, when the expression was handled
*/
const handleAccessExport = (expr, base, members, call) => {
if (HarmonyExports.isEnabled(parser.state)) return;
if (members.length === 0) {
bailout(
`${base} is used directly at ${formatLocation(
/** @type {DependencyLocation} */ (expr.loc)
)}`
);
}
if (call && members.length === 1) {
bailoutHint(
`${base}${propertyAccess(
members
)}(...) prevents optimization as ${base} is passed as call context at ${formatLocation(
/** @type {DependencyLocation} */ (expr.loc)
)}`
);
}
const dep = new CommonJsSelfReferenceDependency(
/** @type {Range} */ (expr.range),
base,
members,
Boolean(call)
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addDependency(dep);
/** @type {BuildMeta} */ (parser.state.module.buildMeta).treatAsCommonJs =
true;
if (call) {
parser.walkExpressions(call.arguments);
}
return true;
};
parser.hooks.callMemberChain
.for("exports")
.tap(PLUGIN_NAME, (expr, members) =>
handleAccessExport(expr.callee, "exports", members, expr)
);
parser.hooks.expressionMemberChain
.for("exports")
.tap(PLUGIN_NAME, (expr, members) =>
handleAccessExport(expr, "exports", members)
);
parser.hooks.expression
.for("exports")
.tap(PLUGIN_NAME, (expr) => handleAccessExport(expr, "exports", []));
parser.hooks.callMemberChain
.for("module")
.tap(PLUGIN_NAME, (expr, members) => {
if (members[0] !== "exports") return;
return handleAccessExport(
expr.callee,
"module.exports",
members.slice(1),
expr
);
});
parser.hooks.expressionMemberChain
.for("module")
.tap(PLUGIN_NAME, (expr, members) => {
if (members[0] !== "exports") return;
return handleAccessExport(expr, "module.exports", members.slice(1));
});
parser.hooks.expression
.for("module.exports")
.tap(PLUGIN_NAME, (expr) =>
handleAccessExport(expr, "module.exports", [])
);
parser.hooks.callMemberChain
.for("this")
.tap(PLUGIN_NAME, (expr, members) => {
if (!parser.scope.topLevelScope) return;
return handleAccessExport(expr.callee, "this", members, expr);
});
parser.hooks.expressionMemberChain
.for("this")
.tap(PLUGIN_NAME, (expr, members) => {
if (!parser.scope.topLevelScope) return;
return handleAccessExport(expr, "this", members);
});
parser.hooks.expression.for("this").tap(PLUGIN_NAME, (expr) => {
if (!parser.scope.topLevelScope) return;
return handleAccessExport(expr, "this", []);
});
// Bailouts //
parser.hooks.expression.for("module").tap(PLUGIN_NAME, (expr) => {
bailout();
const isHarmony = HarmonyExports.isEnabled(parser.state);
const dep = new ModuleDecoratorDependency(
isHarmony
? RuntimeGlobals.harmonyModuleDecorator
: RuntimeGlobals.nodeModuleDecorator,
!isHarmony
);
dep.loc = /** @type {DependencyLocation} */ (expr.loc);
parser.state.module.addDependency(dep);
return true;
});
}
}
module.exports = CommonJsExportsParserPlugin;