From 42cb3627a830534a4002a1ebfcda289443f307aa Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Thu, 28 May 2026 01:29:10 +0200 Subject: [PATCH] fix(buid): fix JS bundler on import with alias already declared --- build.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/build.rs b/build.rs index 24712d81..1635803b 100644 --- a/build.rs +++ b/build.rs @@ -558,7 +558,7 @@ fn strip_esm_syntax( if !t.ends_with(';') && !t.contains(" from ") { skipping = true; // multi-line import } - let aliases = collect_import_aliases(t); + let aliases = collect_import_aliases(t, declared_namespaces); if aliases.is_empty() { out.push('\n'); } else { @@ -628,7 +628,9 @@ fn try_strip_export_prefix(line: &str) -> Option { /// For `import { A, B as C, D as E } from '…'` return `"const C = B;\nconst E = D;"`. /// Returns an empty string when there are no aliases. -fn collect_import_aliases(stmt: &str) -> String { +/// Aliases already present in `declared` are skipped; newly emitted aliases are +/// inserted into `declared` so that subsequent files don't re-declare them. +fn collect_import_aliases(stmt: &str, declared: &mut std::collections::HashSet) -> String { let brace_start = match stmt.find('{') { Some(i) => i + 1, None => return String::new(), @@ -645,6 +647,12 @@ fn collect_import_aliases(stmt: &str) -> String { if let Some(as_pos) = b.find(" as ") { let orig = b[..as_pos].trim(); let alias = b[as_pos + 4..].trim(); + // Already declared earlier in the bundle — skip to avoid + // `SyntaxError: Identifier already declared`. + if declared.contains(alias) { + continue; + } + declared.insert(alias.to_string()); if !out.is_empty() { out.push('\n'); }