diff --git a/src/bundler/linker_context/scanImportsAndExports.rs b/src/bundler/linker_context/scanImportsAndExports.rs index 9d6fdab93a9a..0115df5c1882 100644 --- a/src/bundler/linker_context/scanImportsAndExports.rs +++ b/src/bundler/linker_context/scanImportsAndExports.rs @@ -1291,9 +1291,18 @@ pub(crate) fn scan_imports_and_exports( Index::source(source_index), )?; col!(ast_flags_list)[id].insert(AstFlags::USES_EXPORTS_REF); - col!(import_records_list)[id].as_mut_slice()[*import_record_index as usize] - .flags - .insert(ImportRecordFlags::CALLS_RUNTIME_RE_EXPORT_FN); + let flags = &mut col!(import_records_list)[id].as_mut_slice() + [*import_record_index as usize] + .flags; + flags.insert(ImportRecordFlags::CALLS_RUNTIME_RE_EXPORT_FN); + // `convert_stmts_for_chunk` prints an external one as + // `import * as ns`, and the printer names `ns` only for + // a record that contains an import star. + if !rec_source_index.is_valid() + && output_format.keep_es6_import_export_syntax() + { + flags.insert(ImportRecordFlags::CONTAINS_IMPORT_STAR); + } re_export_uses += 1; } } diff --git a/test/bundler/esbuild/importstar.test.ts b/test/bundler/esbuild/importstar.test.ts index a4ccd7cd8a25..7717eeabea0d 100644 --- a/test/bundler/esbuild/importstar.test.ts +++ b/test/bundler/esbuild/importstar.test.ts @@ -1437,6 +1437,48 @@ describe.concurrent("bundler", () => { stdout: '{"inner":{"b":456},"a":123,"b":456}', }, }); + // ESM output imports an inner file's external `export *` as a namespace, for + // `__reExport` to copy from. + itBundled("importstar/ReExportStarEntryPointAndInnerFileExternalESM", { + files: { + "/entry.js": /* js */ ` + export * from 'a' + import * as inner from './inner.js' + export { inner } + `, + "/inner.js": `export * from 'b'`, + }, + format: "esm", + external: ["a", "b"], + runtimeFiles: { + "/test.js": /* js */ ` + import * as out from './out.js' + console.log(JSON.stringify(out)) + `, + "/node_modules/a/index.js": `export const a = 123;`, + "/node_modules/b/index.js": `export const b = 456;`, + }, + run: { + file: "/test.js", + stdout: '{"a":123,"inner":{"b":456}}', + }, + }); + itBundled("importstar/ReExportStarBuiltinFromLazyModule", { + files: { + "/entry.js": /* js */ ` + import * as ns from './re.js' + const lazy = await import('./lazy.js') + console.log(typeof ns.join, ns.own, typeof lazy.readFileSync) + `, + "/re.js": `export * from 'node:path'; export const own = 1`, + "/lazy.js": `export * from 'node:fs'`, + }, + target: "bun", + format: "esm", + run: { + stdout: "function 1 function", + }, + }); itBundled("importstar/ReExportStarEntryPointAndInnerFile", { files: { "/entry.js": /* js */ `