Re-export default?

# Jason Kuhrt (9 years ago)

I was prompted to bring this issue to es-discuss. babel/babel#826

It is my confusion about why this syntax does not work:

export foo from './foo'

More details are in the issue but the gist is that sometimes it is actually quite handy to export just defaults internally and then re-export thing as a “bag” of named exports. This is not currently “easy”. I assume this was discussed/considered. I’d be curious what the rationale was.

# Kevin Smith (9 years ago)
export foo from './foo'

I personally would find such a construct terribly confusing. But then again I find the entire default export business terribly confusing. ; )

# caridy (9 years ago)

Yes, that syntax is incorrect and confusing.

There was an overside from our end to provide a way to re-export only the default export from another module, and this is something we plan to revisit for ES7/2016. Probably something like this:

 export default from “foo”;

this is just sugar for:

 export {default} from “foo”;

which is perfectly supported in ES6, including the ability to rename it:

 export {default as something} from “foo”;
# Jason Kuhrt (9 years ago)

I hear the verdict but not any substantial rationale; why is it “confusing”?’

@caridy regarding your examples for JS2016 wouldn’t this

export default from “foo”;

just re-export one module’s default as another module’s default, right?

In my use-case, in order to map n-number of default-export functions to named-export functions I would have to do this ad-infinitum:

export {default as a} from “./a”
export {default as b} from “./b”
export {default as c} from “./c”
export {default as d} from “./d”
export {default as e} from “./e”
...

I’m not saying my syntax for my use-case is amazing, I’m just working within the confines of JS. Other languages such as Go have their own interesting approaches to modules that we cannot really consider in JS due to needing a high level of semantic mapping to legacy CJS Modules.

# Matthew Robb (9 years ago)

Why not simply

import a from "a";
import b from "b";

export { a, b };
# caridy (9 years ago)

On Feb 19, 2015, at 8:18 AM, Jason Kuhrt <jasonkuhrt at me.com> wrote:

I hear the verdict but not any substantial rationale; why is it “confusing”?’

what it’s confusing from your initial question (export foo from “foo”) is the foo, which looks like a local identifier.

@caridy regarding your examples for JS2016 wouldn’t this

export default from “foo”;

just re-export one module’s default as another module’s default, right?

Yes, probably. But that is up for discussion, a discussion that hasn't started yet.

In my use-case, in order to map n-number of default-export functions to named-export functions I would have to do this ad-infinitum:

export {default as a} from “./a”
export {default as b} from “./b”
export {default as c} from “./c”
export {default as d} from “./d”
export {default as e} from “./e”
...

I’m not saying my syntax for my use-case is amazing.

Sure. we are talking about sugar here. If that sugar is confusing, we will not add it. IMO export foo from “foo” is certainly confusing, especially because it does not denote the intent, while export {default as a} from “a” is very clear.

# Matthew Robb (9 years ago)

Just curious if this meets the use cases being discussed here, @caridy @jason ? ​

# Jason Kuhrt (9 years ago)

This is another pattern I could take yup.

Kevin pointed that if I suck it up and move all my modules toward named-exports then my problems go away too. The reason I am using default internally was that I had modules depending on others which are all uniformly single-function modules (react components to be specific). So it felt confusing to have this syntax internally:

import { foo } from ‘../foo’

When what I’m really trying to express is:

import foo from ‘../foo’

But ultimately if I am willing to accept that internally I use the former syntax then my re-export expressions are fine:

export * from ‘./foo'

These are small details but added up they matter. Generally I’m happy with modules though. The only other gripe I have is not being able to import each export naked into a namespace like this:

import * from ‘./foo’

Haskell etc. allow this (actually its a bit richer/better but yeah, basically). Often namespacing is what you want, not always.

# caridy (9 years ago)

On Feb 19, 2015, at 7:50 PM, Jason Kuhrt <jasonkuhrt at me.com> wrote:

This is another pattern I could take yup.

Kevin pointed that if I suck it up and move all my modules toward named-exports then my problems go away too. The reason I am using default internally was that I had modules depending on others which are all uniformly single-function modules (react components to be specific). So it felt confusing to have this syntax internally:

import { foo } from ‘../foo’

When what I’m really trying to express is:

import foo from ‘../foo’

But ultimately if I am willing to accept that internally I use the former syntax then my re-export expressions are fine:

export * from ‘./foo’

In my mind, this is good for proxy modules, shims, and other edge cases, but keep in mind that excessive usage of this (e.g.: multiple export *… in the same module) can become a refactor hazard.

These are small details but added up they matter. Generally I’m happy with modules though. The only other gripe I have is not being able to import each export naked into a namespace like this:

import * from ‘./foo’

that’s exactly what import * as foo from “./foo” does it :)

# Jason Kuhrt (9 years ago)

I think you misunderstood my comment about

import * from ‘./foo’

I am aware of

import * as foo from ‘./foo’

and that is fine. My former example is the desire to have foo’s exports injected as-is into the module’s scope (bar vs foo.bar, etc.). There are times where this is desirable, wherein enumerating { bar1, bar2, bar3, barN... } is just a waste of time and maintenance headache.

As for refactoring hazards I can appreciate that JavaScript has a lot more to protect against than strongly typed languages. Refactoring in JavaScript is generally unsafe for any number of reasons.

# caridy (9 years ago)

Jason, the most important feature of ES modules is that they are statically verifiable. Something like import * from “./foo” goes against that principle because you cannot know ahead of time what are those specifiers. Essentially, you will have to type those specifiers no matter what :), no sugar will save you from that.

# Jason Kuhrt (9 years ago)

It doesn’t seem like an impossible problem since other platforms solve this fine without compromising on static analyzability (e.g. Haskell I imagine). But I must admit I’m completely unfamiliar what particular sticking points in the JavaScript platform particularly rule out the possibility of this feature.

# Jason Kuhrt (9 years ago)

Seems like more maintenance given the duplication and your spreading the footprint of something that should be expressed in one line if it really is a simple re-export semantic that is trying to be expressed.

# Jason Kuhrt (9 years ago)

This proposal would solve my issues: leebyron/ecmascript-more-export-from, leebyron/ecmascript-more-export-from

And alas it seems I was correct that this is not an impossible problem to solve at all.