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


結論

Vueコンポーネントでnamed exportは使えない。
VuejsのGitHub IssueでVueフレームワーク創設者のEvan Youさんが「 Vueのコンポーネントはdefault exportが必須です 」とコメントしていた。
default export じゃなきゃだめ ・・・てことはつまり named export は使えないのか。と判断した話。

Github Issue:
https://github.com/vuejs/vue-loader/issues/1234

回答原文の一部:

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

ストーリー

はじまり

JavaScriptではnamed export使った方がいいよっていう記事を拝読した。

ES modulesのexport defaultは使わないほうがよい
JavaScriptのexport defaultアンチパターンについて、検証してみた

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

やったこと

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

変更前 (default export)

App.vue
import HelloWorld from './components/HelloWorld.vue'

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

変更後 (named export)

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

エラーにぶつかる

すると画面は真っ白になり、開発者ツールのコンソールに以下のエラーが出る。
Uncaught TypeError: Cannot set property 'render' of undefined

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

"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&'

エラーを調べる

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

Stack OverflowのQ&A
Cannot set property 'render' of undefined
Uncaught TypeError: Cannot Set Property 'Render' of Undefined
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
(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

(TL;DR: default exportは必須だしそれは変わらないです。)

と回答されている。

結論にいたる

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

まとめ

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