【Vue】コンポーネントでnamed exportは使えないと知った話

# 結論
**Vueコンポーネントで`named export`は使えない。**

Vuejsの[Github Issue](https://github.com/vuejs/vue-loader/issues/1234)でVueフレームワーク創設者のEvan Youさんが「 Vueのコンポーネントはdefault exportが必須です」とコメントしていた。
`default export` じゃなきゃダメ・・・ってことはつまり `named export` は使えないのか。と判断した話。



回答原文の一部:
>TL;DR: the component must be the default export and this is not going to change


# ストーリー
## はじまり
JavaScriptでは`named export`使った方がいいよっていう記事を拝読した。

・ [ES modulesのexport defaultは使わないほうがよい](https://gfx.hatenablog.com/entry/2017/11/24/135343#f-6d4ae8a4)
・ [JavaScriptのexport defaultアンチパターンについて、検証してみた](https://qiita.com/genshun9/items/4a00aa6c709b9f024821)

じゃあVueでもコンポーネントも`named export`にしたほうがいいじゃん！
てことで実装したけど上手くいかなかった。

## やったこと

Vue CLIでプロジェクトを作成。
元から作成されている`App.vue` と`HelloWorld.vue`を`named export
` に変えてみる。

### 変更前 (default export)

```js:App.vue
import HelloWorld from './components/HelloWorld.vue'

```

```vue:HelloWorld.vue
<script>
export default {
    name: 'HelloWorld',
    props: {
    msg: String
  }
}
</script>
```

↓

### 変更後 (named export)

```js:App.vue
import  { HelloWorld }  from './components/HelloWorld.vue';
```

```vue:HelloWorld.vue
<script>
export const HelloWorld = {
    name: 'HelloWorld',
    props: {
    msg: String,
  },
};
</script>
```

## エラーにぶつかる

すると画面は真っ白になり、開発者ツールのコンソールに以下のエラーが出る。
`Uncaught TypeError: Cannot set property 'render' of undefined`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284077/e244d4e5-35c7-7c5f-9beb-6580a84fb649.png)

ターミナルには以下の警告が出る。

```
"export 'default' (imported as 'mod') was not found in '-!../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../node_modules/babel-loader/lib/index.js!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./HelloWorld.vue?vue&type=script&lang=js&'
```

![7EB7E531-BD75-4430-823D-80D0F00A2784.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284077/1d77d0c6-23b8-d4de-f3dc-ef7c6016c8e5.jpeg)

## エラーを調べる 🔍

これらのエラーは、Vueでdefault exportが正しく設定されていないと出るらしい。

Stack OverflowのQ&A
・ [Cannot set property 'render' of undefined](https://stackoverflow.com/questions/51021348/cannot-set-property-render-of-undefined)
・ [Uncaught TypeError: Cannot Set Property 'Render' of Undefined](https://stackoverflow.com/questions/58511705/uncaught-typeerror-cannot-set-property-render-of-undefined)
・ [Nuxt export 'default' (imported as 'mod') was not found](https://stackoverflow.com/questions/55614771/nuxt-export-default-imported-as-mod-was-not-found)

## 原因を調べる👀

さらに調べて、VueのGitHubでこんなIssueを見つけた

[Allow named exports for .vue components. Don't require having a default export #1234](https://github.com/vuejs/vue-loader/issues/1234)
(**Vueでnamed exportを使わせてください。default exportではなく。**)

やりとりを一部抜粋して訳すと・・・
>seems like vue-loader is looking for a default export by default

(**named exportを使おうとしても、vue-loaderは最初にdefault exportを確認する仕様になっているようで、警告が出てしまうのですが・・**)

という問に対して、
>The component itself must be the default export. That's a requirement.

（**default exportは必須です。**）

という回答が来ており、
その後もさらに、

>TL;DR: the component must be the default export and this is not going to change
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284077/b9798a08-48bb-63bb-8da6-e1e45871f9bf.png)

(**HMRとかCSS injectionとかscoped CSSとか critical CSSとかの機能・・・これらは全部正確にexportされることが重要です。自由に命名できるnamed exportを許容したら、動かなくなってしまいます。あと、一部のツール(ESLintのプラグインなど)はdefault exportされること前提で作られてます。なので結論、default exportは必須で、これは今後も変わることはないと思います。**)

と説明されている。
(ふわっとした翻訳。自信ないのですが多分こんな感じのことを言ってる...)



## 結論にいたる

Vueの仕様上、コンポーネントは`default export`しか使えないらしいことがわかった。
Vueフレームワーク創設者のEvan Youさんが直々に無理だと言っているので、named exportは使えないんだろうと判断した。


# まとめ
Vueのコンポーネントでは `named export` は使えないけど、　
それ以外の場所なら使えると思うので、また試してみようと思う。