Skip to content

Allow named exports for .vue components. Don't require having a default export #1234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
o-alexandrov opened this issue Apr 10, 2018 · 8 comments

Comments

@o-alexandrov
Copy link

o-alexandrov commented Apr 10, 2018

What problem does this feature solve?

I know that it is subjective to some extend, but there are proponents of named exports and I am one of them:

Most important aspect for me is the ability to refactor in less time, when dealing with named exports.

People who don't care about the consistence in code or just by a mistake might import giving a different name every time or even once.

Then, the inconsistency will increase the complexity.

Hence, ALLOW NAMED EXPORTS, so there would be an opportunity to name all of the Vue components and prevent the possibility of people, importing same module giving a different name (obviously, there would still be export {module as anotherName} from './path'), but no typos and still better organization of code.

What does the proposed API look like?

Don't require having a default export.
Export .vue components as:

// App.vue
export const app = {}
// instead of (without prohibiting default exporting for backwards compatibility)
export default {}
@yyx990803
Copy link
Member

yyx990803 commented Apr 10, 2018

This is already supported since 13.6.0.

@o-alexandrov
Copy link
Author

o-alexandrov commented Apr 10, 2018

@yyx990803

No, it seems that it isn't supported.
I have tried it before saying it doesn't work as expected.

// app.js
import { app } from "./App.vue"
// instead of the following
// import App from "./App.vue"
// App.vue
export const app = {
// instead of the following
// export default {

Here is a warning message that I received:

22:2-16 "export 'default' (imported as '__vue_script__') was not found in '!!bab
el-loader?{"presets":[["env",{"modules":false,"targets":{"browsers":["> 1%","las
t 2 versions","IE > 8"]}}]],"plugins":["transform-runtime","transform-object-res
t-spread","syntax-dynamic-import"],"comments":false}!../../node_modules/vue-load
er/lib/selector?type=script&index=0!./App.vue'

seems like vue-loader is looking for a default export by default

@yyx990803
Copy link
Member

The component itself must be the default export. That's a requirement.

@fungus1487
Copy link

Is there any means to sidestep this? It really makes refactoring a large project a nightmare, the alias allows the codebase and naming to diverge on a per file basis and unless you are religiously strict and review any Vue component renaming it has the potential to become inconsistent.

This is definitely not a problem on small to medium scale applications but we are currently porting away from a large product to Vue and this is causing us some concern going forward.

@RobertGres
Copy link

RobertGres commented Jun 27, 2018

Right now I have a situation where I'd like to create some companion components, which are going to be used only within context of the main component, since they are going to be specifically tailored for that component.
In component file:

export default {...}
export const PaneButton = {...}
export const PaneNotice = {...}

And in client file I'd like to do this:

import Pane, {PaneNotice, PaneButton} from './Pane'
...
<Pane>
    <template slot="toolbar">
        <PaneButton title="Open this"/>
        <PaneButton title="Open that"/>
    </template>
    <template slot="notices" v-if="notices">
        <PaneButton v-for="notice in notices" text="notice.text"/>
    </template>
</Pane>

Funny thing is that it works in typescript, but unfortunately typescript is pretty much useless with vue ( it requires too much fiddling and provides too little help)

@fungus1487
Copy link

I haven't found TypeScript to be useless with Vue, with the right IDE it works pretty well but I have resorted to barrelling the components like so.

// Component1.vue
@Component({
  components: {},
})
export default class Component1 extends Vue { }
// index.ts
import Component1 from './Component1.vue';
export { Component1 };

@jejacks0n
Copy link

jejacks0n commented Jul 30, 2018

I found myself wanting to do the same thing here.

The ambiguous nature of nameing the component in the exported object and filename and what it can be named on import is too flexible for large projects and I would like to be able to force the import to be named the same as what I want to call it on export.

@yyx990803
Copy link
Member

Features like hot module replacement, CSS injection, scoped CSS, SSR critical CSS collection all depend on being able to precisely locate the exported component - it will not work if the component can be exported as an arbitrarily named component. In addition, there are tools (ESLint plugin, for example) that are based on the assumption of the component being the default export.

TL;DR: the component must be the default export and this is not going to change.

@vuejs vuejs locked and limited conversation to collaborators Jul 30, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants