diff --git a/crates/oxc_minifier/src/peephole/normalize.rs b/crates/oxc_minifier/src/peephole/normalize.rs index 70136b9c5bc0f..c64a9a32eefdf 100644 --- a/crates/oxc_minifier/src/peephole/normalize.rs +++ b/crates/oxc_minifier/src/peephole/normalize.rs @@ -243,18 +243,21 @@ impl<'a> Normalize { e.argument = ctx.ast.expression_numeric_literal(ident.span, 0.0, None, NumberBase::Decimal); } - fn set_no_side_effects(pure: &mut bool, callee: &Expression<'a>, ctx: &TraverseCtx<'a>) { + fn set_no_side_effects( + pure: &mut bool, + callee: &Expression<'a>, + ctx: &TraverseCtx<'a>, + ) -> Option<()> { if !*pure { - if let Some(ident) = callee.get_identifier_reference() { - if let Some(symbol_id) = - ctx.scoping().get_reference(ident.reference_id()).symbol_id() - { - if ctx.scoping().no_side_effects().contains(&symbol_id) { - *pure = true; - } - } + let ident = callee.get_identifier_reference()?; + // The `reference_id` may be `None`(e.g. after `ReplaceGlobalDefines` plugin) after previous passes. + let symbol_id = ctx.scoping().get_reference(ident.reference_id.get()?).symbol_id()?; + + if ctx.scoping().no_side_effects().contains(&symbol_id) { + *pure = true; } } + Some(()) } } diff --git a/napi/transform/test/transform.test.ts b/napi/transform/test/transform.test.ts index 0401df18572ce..620ef5da0c9bc 100644 --- a/napi/transform/test/transform.test.ts +++ b/napi/transform/test/transform.test.ts @@ -244,6 +244,26 @@ describe('define plugin', () => { }); expect(ret.code).toEqual('console.log({ __TEST_DEFINE__: "replaced" });\n'); }); + + it('should not panic when transform a local variable to a global variable', () => { + // https://github.com/rolldown/rolldown/issues/4261 + const code = `function load(url, successCallback, errorCallback) { + var xhr = new XMLHttpRequest(); + xhr.send(null); +}`; + const ret = transform('test.ts', code, { + define: { + 'XMLHttpRequest': 'undefined', + }, + }); + expect(ret.code).toEqual( + `function load(url, successCallback, errorCallback) { + var xhr = new undefined(); + xhr.send(null); +} +`, + ); + }); }); describe('inject plugin', () => {