ホームページ制作を大阪で安く頼むならプロットハブ!

ホームページ制作を大阪で安く頼むならプロットハブ!
毎月5社限定企画実施中

プロットハブ技術ブログ

Nuxt3にcomposableを作ったがネストされると自動インポートがうまくいかない

Ryota Ono

Ryota Ono

2024/6/28

こんにちは!株式会社プロットハブのエンジニア小野です。
今回はNuxt3でcomposableを作った際にネストされると自動インポートがうまくいかない問題について解決方法を共有します。

現在のディレクトリ構成

作成してcomposablesを追加しただけの標準的なNuxt3のディレクトリ構成です。

├── app.vue
├── composables
│    ├── useTest.ts
│    └── user
│        └── useUser.ts
├── nuxt.config.ts
├── package.json
├── pages
├── public
├── server
└── tsconfig.json

composableとは

Vue3のComposition APIを使って、ロジックを再利用するための関数をまとめたものです。
UIとロジックを分離することで、コードの再利用性を高めることができます。
以下のように作成してコンポーネントなどで使用します。
composables直下にあるファイルは自動でインポートされるため、useTestをインポートする際にuseTestのファイル名を指定する必要はありません。

composables/useTest.ts:

export function useTest() {
  const test = ref('testです')

  return {
    test,
  }
}

pages/index.vue:

<script lang="ts" setup>
const { test } = useTest()
</script>

<template>
    <div class="">
        <h1>Test</h1>
        <p>{{ test }}</p>
    </div>
</template>

以下のようにcomposables/useTest.tsに作成した「testです」を返す関数を作成し、pages/index.vueで使用しています。
composables/useTest.tsのサンプル

ネストされたcomposableを作成

composables/user/useUser.tsを作成し、以下のようにuser1を返す関数を作成します。  

import { ref } from 'vue'

export function useUser() {
  const user = ref('user1')

  return {
    user,
  }
}

pages/index.vueに以下のようにuseUserをインポートして使用するとどうなるでしょうか。

<script lang="ts" setup>
const { test } = useTest()
const { user } = useUser()
</script>

<template>
    <div class="">
        <h1>Test</h1>
        <p>{{ test }}</p>
        <h1>User</h1>
        <p>{{ user }}</p>
    </div>
</template>

500エラーになり「useUser is not defined」と表示されます。
composables/user/useUser.tsのサンプル

composableはディレクトリ直下にあるファイルのみが自動でインポートされるため、ネストされたcomposableは自動でインポートされないためエラーが発生します。

ファイルのスキャン方法

使用するファイルでimportする

使用したいファイルでimportするという方法があります。
以下を追加すると読みこまれるためエラーが解消されます。

import { useUser } from "~/composables/user/useUser";

pages/index.vue:

<script lang="ts" setup>
import { useUser } from "~/composables/user/useUser";
const { test } = useTest()
const { user } = useUser()
</script>

<template>
    <div class="">
        <h1>Test</h1>
        <p>{{ test }}</p>
        <h1>User</h1>
        <p>{{ user }}</p>
    </div>
</template>

これでエラーが解消され、正常に表示されるようになりますが使用する箇所で毎回importする必要があるため、コードが冗長になります。

composables/index.tsを作成

composables/index.tsを作成し、以下のようにネストされたcomposableをインポートする方法もあります。
composables/index.ts:

export { useUser } from './user/useUser'

Nuxt3はcomposables直下のファイルを自動でインポートするため、composables/index.tsを作成し、ネストされたcomposableをインポートすることでエラーが解消されます。
これはcomposables直下のファイルを自動でインポートする仕組みを利用しています。
pages/imdex.vue:

<script lang="ts" setup>
const { test } = useTest()
const { user } = useUser()
</script>

<template>
    <div class="">
        <h1>Test</h1>
        <p>{{ test }}</p>
        <h1>User</h1>
        <p>{{ user }}</p>
    </div>
</template>
nuxt.config.tsに設定

nuxt.config.tsに以下の設定を追加することで、composables直下のファイル以外も自動でインポートされるようになります。
公式サイトにも記載されている内容でnuxt.config.tsに記載するだけで全てのcomposableを自動でインポートすることができます。

export default defineNuxtConfig({
  imports: {
    dirs: [
      'composables',
      'composables/*/index.{ts,js,mjs,mts}',
      'composables/**'
    ]
  }
})
結果

どの方法を選択してもエラーが解消され、正常に表示されるようになります。
composables/user/useUser.tsの結果

まとめ

Nuxt3でcomposableを作成する際にネストされると自動でインポートされない問題について解決方法を共有しました。
個人的にはnuxt.config.tsに設定を追加する方法が一番スマートだと思いますが知らないとimportして実装してしまう可能性があるのでドキュメントを作成ししっかりとルールを決めておく必要があると感じました。

プロットハブはソフトウェア開発を
支援しています。
ご興味のある方はぜひお気軽に
ご相談ください。

一覧ページに戻る

全カテゴリ一覧

全タグ一覧

関連記事

コメント

コメントを残す

コメントが承認されると公開されます。※の入力欄は必須項目です

ホームページ制作が毎月5社限定5万5千円から!ご依頼の方はコチラ!