Do api.exports override ES6 import aliasing?

The section on Modular Package Structure in the Modules doc states:

When you use api.mainModule, the exports of the main module are exposed globally as Package[“my-modular-package”], along with any symbols exported by api.export, and thus become available to any code that imports the package. In other words, the main module gets to decide what value of Foo will be exported by api.export, as well as providing other properties that can be explicitly imported from the package:

// In an application that uses my-modular-package:
import {Foo as ExplicitFoo, bar} from "meteor/my-modular-package";
console.log(Foo); // Auto-imported because of api.export.
console.log(ExplicitFoo); // Explicitly imported, but identical to Foo.
console.log(bar); // Exported by server.js or client.js, but not auto-imported.

Note in particular the line:

console.log(Foo); // Auto-imported because of api.export.

Aliases in imports are usually used to resolve namespace clashes. i.e. If two modules contain a named export for “Foo”, we’ll need to alias one of them to something that doesn’t clash.

If the above comment is true, then is not the whole reason for using an alias in an import being subverted? It seems to me that Meteor should not be auto-importing the api.export in a case where an explicit import has renamed it.

Where is the problem here, in the documentation, the implementation, or my understanding?

1 Like

@tmeasday, @sashko I am currently working on a development tool project (one that provides semi-automatic management of import statements) where the answer to this question might have some minor consequence. Do either of you know?

Hey Rhett,

I’m not sure, but I reckon a little bit of experimentation will yield the answer!

Oh, I didn’t see the full context above.

The linker (the old auto-import system) ends up putting Foo on window if you use the package in application scope.

Importing something as Foo will make a local variable call Foo. So that would shadow the global window.Foo in this case.

So, isn’t that a bit of a problem? The only good reason I can think of to use the “Foo as ExplicitFoo” as shown in the documentation is to handle a situation like

import {Foo} from 'fooBar';
import {Foo as ExplicitFoo} from 'barFoo';

And what this piece of documentation seems to be saying to me is that that is broke. Instead of ‘Foo’ pointing to fooBar.Foo and ExplicitFoo pointing to barFoo.Foo, I could end up with both pointing to barFoo.Foo, right?

Are you also saying that it may work different on server versus client?