🍍

pinia/nuxt@0.5.0 に追加されたstoresDirsオプションを試す

2023/10/14に公開

はじめに

こんにちは、がんがんです。

2023.10.13 に@pinia/nuxt@0.5.0がリリースされましたね。本リリースでは Module Options にブレイキングチェンジがありました (参照: CHANGELOG)。

本記事では新しく追加されたstoresDirsオプションについて試してみます。

まとめ: 従来通りに Auto Imports して使いたい

nuxt.config.ts
export default defineNuxtConfig({
  // ... other options
  imports: {
    presets: [
      {
        from: "pinia",
        imports: [
          // 以下2つは Unit Test で主に利用
          "createPinia",
          "setActivePinia",
        ],
      },
    ],
  },
  pinia: {
    // NOTE: Nested 対応
    storesDirs: ["./stores/**"],
  },
});

ModuleOptions: storesDirs

@pinia/nuxtの Module Options は公式ドキュメントに記載があります。

https://pinia.vuejs.org/api/interfaces/pinia_nuxt.ModuleOptions.html

autoImportsプロパティが廃止されstoresDirsプロパティが追加されています。autoImportsプロパティについては下記 PR で議論されていました。

https://github.com/vuejs/pinia/pull/1604

下記 commit で対応されたようです。

https://github.com/vuejs/pinia/commit/70a95ba9b1d6a55aeea72088dfedd478aa4db766

storesDirs の使い方

storesDirsプロパティで実現できる設定は従来imports.dirs で補っていた内容です。

/storesディレクトリを/components/composablesと同じように Auto Imports したい場合、以下のような設定を追加する必要がありました。

nuxt.config.ts
export default defineNuxtConfig({
  // ... other options
  modules: ["@pinia/nuxt"],
  imports: {
    dirs: ["stores"],
  },
  pinia: {
    // ... pinia options
  },
});

storesDirsプロパティが追加されたことで以下のように設定できるようになりました。

nuxt.config.ts
export default defineNuxtConfig({
  // ... other options
  modules: ["@pinia/nuxt"],
- imports: {
-   dirs: ["stores"],
- },
  pinia: {
+   /**
+    * @default ["stores"]
+    * ネストされたディレクトリを指定する場合は glob pattern で指定可能. @example ["./stores/**"]
+    */
+   storesDirs: ["./stores/**"],
  },
});

autoImports プロパティの代用方法は?

今までpinia.autoImportsプロパティに設定していたものはどうすれば良いのでしょうか。実装を見る限り、下記 4 つは@pinia/nuxt側で Auto-Imports されています。

  • usePinia
  • defineStore
  • acceptHMRUpdate
  • storeToRefs
ref: GitHub


では、それ以外の composables はどのように Auto Imports すれば良いのでしょうか。例えば、Unit Test 時によく利用するsetActivePiniacreatePiniaや分割代入時のリアクティビティ保持で利用されるstoreToRefsなどが挙げられるかと思います。

この問題は Nuxt3 が提供するAuto-imports設定を拡張すれば解決します。設定方法は何パターンか可能でした。

1. 'from: pinia' を用いる

1 つ目の方法として考えられるのは pinia から直接 imports する方法です。

nuxt.config.ts
export default defineNuxtConfig({
  imports: {
    presets: [
      {
        from: "pinia",
        imports: ["createPinia", "setActivePinia"],
      }
    ]
  },
});

nuxt prepareを実行し.nuxt/imports.d.tsの差分を見てみます。

.nuxt/imports.d.ts
+ export { createPinia, setActivePinia } from 'pinia';
export { defineStore, acceptHMRUpdate, usePinia, storeToRefs } from '../../node_modules/@pinia/nuxt/dist/runtime/composables';

2. unjs/unimport の Built-in Presets を利用する

Nuxt3 の Auto-imports 機能は unjs/unimport を利用しています。
そのため、unjs/unimport 側で提供しているプリセットを利用することが可能です。

nuxt.config.ts
export default defineNuxtConfig({
  imports: {
    presets: ["pinia"],
  },
});

.nuxt/imports.d.tsを見てみます。確かに 1 つ目とインポート内容が変わっていますね(下記は 1 つ目の設定方法との diff)。

.nuxt/imports.d.ts
- export { createPinia, setActivePinia } from 'pinia';
+ export { createPinia, getActivePinia, mapActions, mapGetters, mapState, mapStores, mapWritableState, setActivePinia, setMapStoreSuffix, storeToRefs } from 'pinia';
export { defineStore, acceptHMRUpdate, usePinia, storeToRefs } from '../../node_modules/@pinia/nuxt/dist/runtime/composables';


本設定のデメリットとして @pinia/nuxt側で 重複 import されているものに以下のような WARNING が表示されます。
nuxt prepare実行時に毎回表示されるのでかなりの頻度で表示されます。

terminal
 WARN  Duplicated imports "defineStore", the one from "pinia" has been ignored

 WARN  Duplicated imports "acceptHMRUpdate", the one from "pinia" has been ignored

現状の Module Options ではautoImports: falseなどが設定できないため上記 WARNING を消すことは難しそうです(そもそもこの設定方法を前提としていない?)。

3. nuxt/kit の 'createResolver()' を用いる

煩わしい WARNING を取り除く 3 つ目の方法としてcreateResolver()を利用する方法です。
createResolver().resolveを利用しnode_modules/@pinia/nuxt/*から直接参照します

nuxt.config.ts
import { createResolver } from "@nuxt/kit";
const { resolve } = createResolver(import.meta.url);

export default defineNuxtConfig({
  imports: {
    presets: [
      {
        from: resolve("./node_modules/@pinia/nuxt/dist/runtime/composables"),
        imports: ["createPinia", "setActivePinia"],
      }
    ],
  },
});

.nuxt/imports.d.tsを見てみるとusePiniadefineStoreacceptHMRUpdatestoreToRefsと一緒にインポートされるように変わってるかと思います。

.nuxt/imports.d.ts
- export { createPinia, setActivePinia } from 'pinia';
- export { defineStore, acceptHMRUpdate, usePinia, storeToRefs } from '../../node_modules/@pinia/nuxt/dist/runtime/composables';
+ export { storeToRefs, createPinia, setActivePinia, defineStore, acceptHMRUpdate, usePinia } from '../../node_modules/@pinia/nuxt/dist/runtime/composables';

余談:createResolver().resolve はpatheをベースにした resolve()です。Node.js 環境固定であればimport { resolve } from 'node:path'でも良さそう。

どの設定方法が最適解か?

本記事読み手の目的として「簡潔に Auto Imports 設定を済ませたい」という目的があると思っています。そのため、筆者所感としてはケース 1 が 1 番楽かなと思ってます。

おわりに

@pinia/nuxt@0.5.1で追加されました。

Pinia公式の GitHub を見ている限りだとstoreToRefsも Auto-Imports 設定として追加されそうです。

https://github.com/vuejs/pinia/pull/2427

本 PR マージ後、storeToRefsの追加の設定も不要になりそうですね。


今月(2023.10)は Vue Fes Japan、Nuxt Conference、来月(2023.11)は Vue.js Conference を控えています。
Vue.js、Nuxt の進化を今後もワクワクしながら観測していきたいですね 🎉

Vue・Nuxt 情報が集まる広場 / Plaza for Vue・Nuxt.

Discussion