プロダクト開発で使えるNuxt Auto-imports設定
はじめに
皆さん、プロダクト開発で Nuxt を利用していますか?
Nuxt はバージョン 3 系に上がり優秀な機能がどんどんと追加されており、v3.10 の現在もその進化は留まるところを知りません。
Nuxt の機能の 1 つに Auto-imports という機能があり非常に優秀な機能です。
ただ、プロダクト・チーム開発においては混乱の元になりかねない危険性をはらんでおり、共通認識の確認やルールの設定が必要になります。
本記事では Auto-imports 機能を実際のプロダクトで利用する場合を想定して設定パターンを整理してみたいと思います。
後述で述べるもの私がプロダクト/個人開発時に検証したものばかりです。ドキュメントに記載されている例は下記記事で紹介しておりますので、合わせてご覧ください。
import 漏れ、import の順番、import 文はチーム開発で揉めがち...
レビュー時の import 漏れ指摘、import の順番、import の alias 設定、import 禁止箇所からの import 利用、未使用モジュールの import、etc...、import 文は問題の中心にいることが多いです。
これらの解決先として、ESLint や Prettier を用いた機械的なチェックが一般的かと思います。ESLint プラグイン・ルールでよく見かけるのは以下のようなものです。
- eslint-plugin-import : import の順番をルール化、自動整列も行う
- eslint-plugin-unused-imports : 未使用の import を自動で削除
- eslint-plugin-import-access : アクセス禁止階層からの import を禁止する
私はprettier-plugin-organize-imports Prettier プラグインを利用し Prettier 側でフォーマットしています。本プラグインについての詳細は下記記事を参照ください。
複数人が参加するプロダクト開発では「どのライブラリを利用し、どのようなルールを運用するのか」が委ねられていることで逆に認識の相違による問題が容易に起こりえます。
Nuxt Auto-imports 機能が提供するのは「そもそも import 文を書かずに利用する」という新たな選択肢です。
未拡張の Auto-imports で可能なこと
ドキュメントのAuto-importsを確認してみます。未拡張の Auto-imports 機能で提供するのは下記の 2 つです。
-
Built-in Auto-imports
Vue, Nuxt composable が import 不要で利用できる機能です。Vue で利用する
ref
、defineProps
やcomputed
、Nuxt で利用するuseFetch
やuseRoute
、useHead
などが import 不要で利用できます。 -
Directory-based Auto-imports
Directory-based Auto-imports 機能により下記 3 つのディレクトリが自動スキャンされます。
components/
composables/
utils/
このままでも十分良いが...
Nuxt 公式が提供する Auto-imports のおかげでかなり楽に開発を進めることができます。ありがたい限りです。
ただ、実際のプロダクト開発を行う場合は(汎用的な機能であるが故に)このままでは使い勝手が良くないケースもあります。そこで実際のプロダクト開発を想定して設定していきます。
事前情報
下記ではcomponents options
、imports options
と分割しています。理由はそれぞれのオプションで出力されるファイルが異なるからです。
components Options
で設定したコンポーネントは.nuxt/components.d.ts
にエクスポートされ、imports Options
で設定した内容は.nuxt/imports.d.ts
にエクスポートされます。
そのため、誤って composable を.nuxt/components.d.ts
にエクスポートした場合、Auto-imports は成功するが上手く動作しないという状況が発生します。
どのファイルにエクスポートされるかが非常に重要になってきますので頭の片隅に入れておいてもらえると助かります。Auto-imports 機能の構造については下記記事で深掘りしています、合わせてご覧ください。
components Options
Q. components/ をネストして利用したい
components ディレクトリがネストしている場合を考えます。例えば、以下のようなケースです。
| components/
--| ui/
----| Button.vue
----| Select/
------| index.vue
--| prod1/
----| AdminPage/
------| Table.vue
------| TableHeader.vue
--| comA.server.vue
components/ui
ディレクトリの切り方はshadcn-vueなどに見られる傾向です。プロダクトの場合は独自の共通コンポーネントを作成しているケースなどで見られるかと思います。
ただ、このままだとコンポーネント名が以下のようになります。Ui~の方は良いですが Prod1~の方は非常に見にくい状態になってます。
<UiButton />
<UiSelect />
<Prod1AdminPageTable />
<Prod1AdminPageTableHeader />
そこでpathPrefix
、prefix
オプションを利用します。
export default defineNuxtConfig({
components: [
// eg: /ui/Select/index.vue -> <UiForm />
{
path: "components/ui",
prefix: "Ui",
},
// eg: /components/prod1/**/Table.vue -> <Table />
{
path: "components/prod1",
pathPrefix: false,
},
],
});
Q. Auto-imports されるコンポーネントを限定したい
コンポーネントカタログとしてStorybookではなくHistoireを利用した場合、Histoire のファイルの拡張子*.story.vue
のようになります。Histoire で利用するファイルはcomponents.d.ts
に含めない方が好ましいと思います。
そこで、extensions
、ignore
オプションを用いて限定することが可能です。
export default defineNuxtConfig({
components: [
{
path: "components/**",
// case: *.stories.ts, types.ts などが同一ディレクトリに含まれる場合
extensions: [".vue"],
// case: Storybook ではなく Histoire を利用している場合
ignore: ["**/*.story.vue"],
},
],
});
Q. components/ ではなく features/ 直下にコンポーネントを配置したい
Nuxt が推奨するディレクトリ構造ではなく features ディレクトリ構造を用いるケースです。
チーム内で Next.js/React.js プロダクトを併用している場合は今までの慣れから採用されるケースが多いと思います。
この場合は以下のような設定になるかと思います。ほとんど前項と同じです。
export default defineNuxtConfig({
components: [
{
path: "features/components/ui",
extensions: [".vue"],
ignore: ["**/*.story.vue"],
prefix: "Ui",
},
],
});
imports Options
Q. Auto Imports をオフにしたい
Auto-imports のメリットは import 内容を隠蔽できることです。しかし、現場によっては 「Auto-imports ではなく全ての import を明示したい」 という現場もあることでしょう。
チームの開発規模・人数が大きくレビュアーが全容を把握していない場合やコンポーネントの数が数百を超えており import を明示的にしないことが逆に開発を妨げ毒になりえるケースです。
ライブラリの移行作業と新規開発を並行で行なっている現場も削除予定のものを誤って import しないように明示したいとなるでしょう。その場合は以下の設定でオフにすることが可能です。
export default defineNuxtConfig({
imports: {
autoImport: false,
},
});
Q. schemas/ や types/を Auto Import したい
zod や valibot でスキーマを定義している場合、型定義を types/に切り出しているケースです。
OpenAPI Generator を用いて IF・型定義を generate しているケースも該当すると思います。
この場合はdirs
オプションを用いてディレクトリ単位で設定します。
export default defineNuxtConfig({
imports: {
dirs: ["schemas/**", "types/**", "{components,layouts}/**/types.ts"],
},
});
zod や valibot を利用する場合はpresets
オプションを用いてそれ自体も Auto-imports すると便利です。
export default defineNuxtConfig({
imports: {
dirs: ["schemas/**", "types/**", "{components,layouts}/**/types.ts"],
presets: [
{
from: "zod",
imports: ["z", "string", "number", "object", "date"],
},
],
},
});
Q. Pinia でも Auto Import したい
Nuxt アプリケーション利用者であれば状態管理として Pinia を利用するケースは多いでしょう。この場合もimports.dirs
オプションを利用すれば良いでしょうか?
Pinia 用の Nuxt module ではモジュール側で Auto-imports のオプションが提供されています。こちらを利用すれば問題ありません。
export default defineNuxtConfig({
modules: ["@pinia/nuxt"],
// @pinia/nuxt@v0.5.0 以上
pinia: {
storesDirs: ["./stores/**"],
},
// @pinia/nuxt@v0.5.0 より前のバージョン
imports: {
dirs: ["stores"],
},
pinia: {
autoImports: ["defineStore", "storeToRefs"],
},
});
ただし、バージョンごとにオプションが異なるため下記の記事を参考にしてください。
-
@pinia/nuxt@v0.5.0
以上: pinia/nuxt@0.5.0 に追加された storesDirs オプションを試す -
@pinia/nuxt@v0.5.0
以前: Pinia さん、Auto-imports できると? (pinia/nuxt@0.4.x 環境)
Q. VeeValidate でも Auto Import したい
Pinia のようにモジュール側が提供しているケースとして VeeValidate があります。こちらもドキュメントの指示に従うだけで Auto-imports 設定が完了します。
export default defineNuxtConfig({
modules: ["@vee-validate/nuxt"],
veeValidate: {
autoImport: true,
},
});
Other case
Q. 特定ディレクトリ直下の components、types をそれぞれインポートしたい
ディレクトリ構成によっては以下のようなケースが考えられると思います。
| components/
--| ui/
----| Card/
------| index.vue
------| index.stories.ts
------| types.ts
------| recipe.ts
この場合は components、imports でそれぞれ設定する必要があります。
export default defineNuxtConfig({
components: [
{
path: "components/**",
extensions: [".vue"],
ignore: ["**/*.story.vue"],
},
],
imports: {
dirs: ["{components,layouts}/**/*.ts"],
},
});
Q. consola、 h3 などの unjs stack を Auto Import して利用したい
Nuxt 内部では Logger のconsaola
、minimal http FW のh3
など多くの UnJS ライブラリが使われています。
この場合は zod、valibot 同様にimports.presets
を利用することで満たせます。
export default defineNuxtConfig({
imports: {
presets: [
{
from: "consola",
imports: ["consola"],
},
],
},
});
また、unjs/unimport
には Exports Auto Scan が可能です。これはローカルにインストールされたパッケージを自動でキャンする機能です。presets の import 対象を限定しない場合はこちらの方がシンプルです。
余談: Exports Auto Scan は 下記イシューで Anthony Fu 氏に教えてもらいました。非常にありがたい 🙏
おわりに
本記事は Nuxt Auto-imports 機能をプロダクト開発に当てはめて書いてみました。今回書いた内容はあくまで 1 例だと思います。
-
「こんなケースでも利用できた」
-
「こんなケースではどうすればいいのか」
などあればコメントまでどんどんお待ちしております 🙌
本記事が Auto-imports を使ってみるきっかけになれば嬉しいですし、ドキュメントと合わせた集合知になれば幸いです。
また、Nuxt Layer での利用ケース、monorepo 構成の場合については検証途中のため別記事で執筆できたらと思います。
関連
公式 Docs / GitHub
-
Nuxt Docs
-
GitHub
- Auto-imports 機能のベースとなった unjs/unimport
- unplugin-auto-import
- unplugin-vue-components
記事
Discussion
いつのまにか
pathPrefix
がglobal
プロパティになりましたかね?こちらだと、
pathPrefix: false
の代わりにglobal: true
を指定することで、うまくいきましたまた、
components
に指定していないコンポーネントもauto-importしたい場合は、最後に(最後に?)文字列として加えてあげる必要があるっぽそうな気がします返信先↓