Import/Export name collision resolution

Viewed 368

Testing in Node JS the following modules layout, looks like local exported definitions always replace external exported in case of name collision (see f1 in B.js).

A.js

export const f1 = 'A'

B.js

export * from './A.js'
export const f1 = 'B'

C.js

import * as A from './A.js'
import * as B from './B.js'
console.log(A.f1)
console.log(B.f1)
> node C.js
// A
// B

Is this a rule? I have not found something about how to manage this in Ecmascript specs.

Does import/export order matter?

Do you see this as a reliable method for extending a module overloading functions and/or adding new ones?

1 Answers

Is this a rule? I have not found something about how to manage this in Ecmascript specs.

Yes, Local exports have priority. Which is, in fact, standardized in the spec:

  1. For each ExportEntry Record e in module.[[LocalExportEntries]], do
    a. Assert: module provides the direct binding for this export.
    b. Append e.[[ExportName]] to exportedNames.
  2. For each ExportEntry Record e in module.[[IndirectExportEntries]], do
    a. Assert: module imports a specific binding for this export.
    b. Append e.[[ExportName]] to exportedNames.

Specifically the starExport in your case is part of:

For each ExportEntry Record e in module.[[StarExportEntries]], do
    (...)
    c. Let starNames be requestedModule.GetExportedNames(exportStarSet).
    d. For each element n of starNames, do
        i. If SameValue(n, "default") is false, then
            1. If n is not an element of exportedNames, then
                a. Append n to exportedNames.

So, to answer your second question:

Do you see this as a reliable method for extending a module overloading functions and/or adding new ones?

Yes, it's reliable because it's specified in the standard.

Related