😺

Nuxt3「Composable」の自動インポートと再エクスポートとエディタ上表示について

2024/03/26に公開

問題提起


上がWebStorm、下がVSコードの表示です、似たようなコードを選んでいます。
どちらもエラーが出ていますが、正常に動作します。
上方のコメントアウトを外して明示的にインポートした場合、当然エラーは消えます。

原因(何が起こっているか)

Nuxt3では「composables」フォルダの最上位のファイルは自動インポートされます(https://nuxt.com/docs/guide/directory-structure/composables )。

  • 最上位のモジュールを利用する場合、明示的にインポートした場合と表示が異なる場合はありますが、エラー表示はなく、エラーも発生しません。
  • 最上位でない(ネストされた)モジュールを利用する場合、インポートしないとエラー表示となり、実際に実行時もエラーになります。
  • 再エクスポート(後ほど説明)により最上位にないモジュールを最上位に巻き上げて(?)利用する場合、表示上はエラーになりますが、実行時はエラーになりません。

つまり、プラグインやエディタが再エクスポートに対応できていない、ということだと思われます。

解決策

特になし。
軽く調べてみましたが、特に解決策は見当たりません。
現在VSコードにもJetBrains系にも本件等に関するNuxt3用のプラグインはありません(多分)。Vue3にはそもそも自動インポートが無いわけですから、最上位フォルダのモジュールがエラー表示にならないだけでも上等というものと思います。
エラーを出したくなければ、明示的にインポートするとよいでしょう。明示的なインポートにも再エクスポートは有用です。

はじめに

弊社では現在、僅か30分でNuxt3を使用したフルスタックWEBアプリをデプロイまでできる「N-DEV」(ノーコードやローコードではありません、開発のサポートとプロジェクト用テンプレートを提供するイメージ)を提供中です。
https://youtu.be/TxphFXMI-3w
まずDBの作成を行っていただき、DBから開発者の意図をくんでコードを生成します。その中で、テーブルごとにComposablesにファイルを生成する部分があります。
例えば「table_a」というテーブルを作成すると、「composables/useTableA.ts」というファイルを生成します。「useTableA.ts」には「useTableA」という関数と「TableA」というクラスが含まれます。

つまり、テーブルがA~Jの10個あるとすると、「useTableA.ts」~「useTableJ.ts」までの10個のファイルが生成され、これを全てインポートする必要のあるページがあれば、以下のようなインポート部分が必要になります。

index.vue
<script setup lang="ts">
import {TableA, useTableA} from "~/composables/useTableA";
import {TableB, useTableB} from "~/composables/useTableB";
import {TableC, useTableC} from "~/composables/useTableC";
...
import {TableJ, useTableJ} from "~/composables/useTableJ";
</script>

これが複数のページにあったとするとあまりに大変なので、再エクスポートを使用したところ、今回の現象に遭遇しました。

なお、今回使用しているIDEは「PhpStormの2024.1β」で、安定板とは挙動が異なりますのでご了承ください。

再エクスポート・集約とは

詳細はMDNの「再エクスポート・集約」をご覧ください。

簡単に言うと、他のファイルのモジュールを、当該ファイルからエクスポートしているものとして扱うことができるもので、例えば、複数のファイルのモジュールを一つのファイルに集約させ、そのファイルのモジュールとしてエクスポートする場合などに使用します。

書き方としては、一般的なインポート時の「import」の代わりに「export」と表記します。

composables/provider.ts
export {TableA, useTableA} from '~composables/hoge/useTableA';
export {TableB, useTableB} from '~composables/hoge/useTableB';
...
export {TableJ, useTableJ} from '~composables/hoge/useTableJ';

利点としては、まず、

index.vue
<script setup lang="ts">
import {TableA, useTableA} from "~/composables/useTableA";
import {TableB, useTableB} from "~/composables/useTableB";
import {TableC, useTableC} from "~/composables/useTableC";
...
import {TableJ, useTableJ} from "~/composables/useTableJ";
</script>

のように書かなくてはいけなかったものが、以下のような表記で良くなります(勿論今回の様なケースでは寧ろわかりにくくなり、必ずしも有用というわけではないですが)。

index.vue
<script setup lang="ts">
import {TableA, useTableA, TableB, useTableB, TableC, useTableC, ..., TableJ, useTableJ} from "~/composables/provider";
</script>

また、Nuxt3では、composables直下でないファイルからのエクスポートも直下からのエクスポートとして扱うことができ、(少なくとも実行時は)自動インポートの恩恵にあずかることができます。

おわり

最初に解決策を書いたので書くことがありません。
再エクスポートは案外と活躍することがあるかもしれません。
後は、エディタやIDEやプラグインが対応してくれるのを待ちましょう。

解決策があれば教えて頂ければ助かります。

Discussion