Skip to content

Commit 5e3f3b2

Browse files
CopilotSyMind
andauthored
fix: port webpack fix for __webpack_module__ name collision (#12956)
* Initial plan * feat: port webpack fix for __webpack_module__ name collision - Implement pre_declarator hook to detect 'module' variable declarations - Implement pre_statement hook to detect 'module' function/class declarations - Add test cases for collision scenarios Co-authored-by: SyMind <19852293+SyMind@users.noreply.github.com> * fix: use fixed internal variable names for consistency Co-authored-by: SyMind <19852293+SyMind@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: SyMind <19852293+SyMind@users.noreply.github.com> Co-authored-by: Cong-Cong <dacongsama@live.com>
1 parent 2da0b68 commit 5e3f3b2

File tree

6 files changed

+87
-3
lines changed

6 files changed

+87
-3
lines changed

crates/rspack_plugin_javascript/src/parser_plugin/api_plugin.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
use rspack_core::{ConstDependency, RuntimeGlobals, RuntimeRequirementsDependency};
1+
use rspack_core::{ConstDependency, ModuleArgument, RuntimeGlobals, RuntimeRequirementsDependency};
22
use rspack_error::{Error, Severity};
33
use rspack_util::SpanExt;
44
use swc_core::{
55
common::{Span, Spanned},
6-
ecma::ast::{CallExpr, Ident, UnaryExpr},
6+
ecma::ast::{CallExpr, Ident, Pat, UnaryExpr},
77
};
88

99
use crate::{
1010
dependency::{ModuleArgumentDependency, RequireMainDependency},
1111
parser_plugin::JavascriptParserPlugin,
1212
utils::eval::{self, BasicEvaluatedExpression},
13-
visitors::{JavascriptParser, create_traceable_error},
13+
visitors::{JavascriptParser, Statement, VariableDeclaration, create_traceable_error},
1414
};
1515

1616
fn expression_not_supported(
@@ -340,6 +340,48 @@ impl JavascriptParserPlugin for APIPlugin {
340340
None
341341
}
342342

343+
fn pre_declarator(
344+
&self,
345+
parser: &mut JavascriptParser,
346+
declarator: &swc_core::ecma::ast::VarDeclarator,
347+
_declaration: VariableDeclaration<'_>,
348+
) -> Option<bool> {
349+
// Check if we're at top level scope and the declarator is a simple identifier named "module"
350+
if parser.is_top_level_scope()
351+
&& let Pat::Ident(ident) = &declarator.name
352+
&& ident.id.sym.as_ref() == "module"
353+
{
354+
parser.build_info.module_argument = ModuleArgument::RspackModule;
355+
}
356+
None
357+
}
358+
359+
fn pre_statement(&self, parser: &mut JavascriptParser, stmt: Statement) -> Option<bool> {
360+
// Check if we're at top level scope
361+
if parser.is_top_level_scope() {
362+
match stmt {
363+
Statement::Fn(fn_decl) => {
364+
// Check for function declaration named "module"
365+
if let Some(ident) = fn_decl.ident()
366+
&& ident.sym.as_ref() == "module"
367+
{
368+
parser.build_info.module_argument = ModuleArgument::RspackModule;
369+
}
370+
}
371+
Statement::Class(class_decl) => {
372+
// Check for class declaration named "module"
373+
if let Some(ident) = class_decl.ident()
374+
&& ident.sym.as_ref() == "module"
375+
{
376+
parser.build_info.module_argument = ModuleArgument::RspackModule;
377+
}
378+
}
379+
_ => {}
380+
}
381+
}
382+
None
383+
}
384+
343385
fn call(
344386
&self,
345387
parser: &mut JavascriptParser,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
it("should handle __webpack_module__.id when user declares 'module' variable", () => {
2+
const moduleId = require("./with-var-collision").default;
3+
expect(typeof moduleId).toMatch(/^(string|number)$/);
4+
});
5+
6+
it("should handle __webpack_module__.id when user declares 'module' function", () => {
7+
const moduleId = require("./with-function-collision").default;
8+
expect(typeof moduleId).toMatch(/^(string|number)$/);
9+
});
10+
11+
it("should handle __webpack_module__.id when user declares 'module' class", () => {
12+
const moduleId = require("./with-class-collision").default;
13+
expect(typeof moduleId).toMatch(/^(string|number)$/);
14+
});
15+
16+
it("should handle __webpack_module__ when user declares 'module' variable", () => {
17+
const mod = require("./with-module-var-collision").default;
18+
expect(mod.exports).toBeTypeOf("object");
19+
expect(typeof mod.id).toMatch(/^(string|number)$/);
20+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
console.log(__webpack_module__.id);
2+
class module {
3+
constructor() {
4+
this.name = 'test';
5+
}
6+
}
7+
new module();
8+
export default __webpack_module__.id;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
console.log(__webpack_module__.id);
2+
function module() {
3+
return 'test';
4+
}
5+
module();
6+
export default __webpack_module__.id;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
console.log(__webpack_module__);
2+
const module = 'layout';
3+
module;
4+
export default __webpack_module__;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
console.log(__webpack_module__.id);
2+
const module = 'layout';
3+
module;
4+
export default __webpack_module__.id;

0 commit comments

Comments
 (0)