Skip to content

[Bug]: keepNames drops the export keyword on multi-declarator exports (export const a = 1, b = 2) #9973

Description

@shulaoda

Reproduction link or steps

REPL (copy the whole line):

https://repl.rolldown.rs/#eNptUEFOxDAM/Irly4JURQJuQZy484JcQuquwrZO1LiwUpW/46ZaoBKXJJ4Zz9hZcUC7YuSerkbK9ma0v3WHQUu65jQLhMRFwMMLPHTwrtfjs+MDFxR8UlD7CK3MC9UO5zSOffpio5ohnv/E/MPsgXFqpiv0NESm10ZDhWFOE5xubSfHP/kq9Msoh4a71TFA5LyIhd3STCTeNKjbyLRIY5sS4EKU3/xExcI2fJNUPeu97qSrZB8u/kzmoyS+LXHA9vGbm8OeMulHcohUHGpIVafNSJ0+VTZ6oSJYvwEvkoOo

The REPL opens with keepNames already enabled and the entry below preloaded.

Or reproduce manually:

  1. Open https://repl.rolldown.rs/
  2. Set index.ts to:
    export const a = 1, b = 2;
    export const c = 3;
  3. In rolldown.config.ts, enable keepNames:
    import { defineConfig } from 'rolldown'
    
    export default defineConfig({
      input: import.meta.input,
      output: {
        keepNames: true,
      },
    })
  4. Look at the generated output.

What is expected?

All three names should be exported, exactly as with keepNames: false:

const a = 1;
const b = 2;
const c = 3;
export { a, b, c };

What is actually happening?

With output.keepNames: true, the multi-declarator export (export const a = 1, b = 2;) loses its export keyword. a and b are silently dropped from the bundle; only the single-declarator export c survives:

const c = 3;
export { c };

a and b are gone.

This is not only silent loss. If another module imports those names, the build fails instead. Given:

// dep.js
export const a = 1, b = 2;

// main.js (entry)
import { a, b } from './dep.js';
console.log(a, b);

keepNames: false builds fine, but keepNames: true aborts with:

[MISSING_EXPORT] "a" is not exported by "dep.js".
[MISSING_EXPORT] "b" is not exported by "dep.js".

So depending on how the multi-declarator export is consumed, keepNames: true either produces a wrong bundle (names missing) or fails the build outright. Single-declarator exports (export const x = 1;) are not affected.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions