Nuxt Nation カンファレンスが開催されます。11月12日〜13日にご参加ください。

プラグイン

Nuxtには、Vueアプリケーションの作成時にVueプラグインなどを利用するためのプラグインシステムがあります。

Nuxtはplugins/ディレクトリ内のファイルを自動的に読み込み、Vueアプリケーションの作成時にロードします。

内部のすべてのプラグインは自動登録されるため、nuxt.configに個別に追加する必要はありません。
ファイル名に.serverまたは.clientサフィックスを使用することで、サーバー側またはクライアント側のみでプラグインを読み込むことができます。

登録済みプラグイン

ディレクトリのトップレベルにあるファイル(またはサブディレクトリ内のインデックスファイル)のみがプラグインとして自動登録されます。

ディレクトリ構造
-| plugins/
---| foo.ts      // scanned
---| bar/
-----| baz.ts    // not scanned
-----| foz.vue   // not scanned
-----| index.ts  // currently scanned but deprecated

foo.tsbar/index.tsのみが登録されます。

サブディレクトリにプラグインを追加するには、nuxt.config.tspluginsオプションを使用できます。

nuxt.config.ts
export default 
defineNuxtConfig
({
plugins
: [
'~/plugins/bar/baz', '~/plugins/bar/foz' ] })

プラグインの作成

プラグインに渡される唯一の引数はnuxtAppです。

plugins/hello.ts
export default 
defineNuxtPlugin
(
nuxtApp
=> {
// Doing something with nuxtApp })

オブジェクト構文プラグイン

より高度なユースケースのために、オブジェクト構文を使用してプラグインを定義することもできます。例えば

plugins/hello.ts
export default 
defineNuxtPlugin
({
name
: 'my-plugin',
enforce
: 'pre', // or 'post'
async
setup
(
nuxtApp
) {
// this is the equivalent of a normal functional plugin },
hooks
: {
// You can directly register Nuxt app runtime hooks here 'app:created'() { const
nuxtApp
=
useNuxtApp
()
// do something in the hook } },
env
: {
// Set this value to `false` if you don't want the plugin to run when rendering server-only or island components.
islands
: true
} })
Alexander LichterによるNuxtプラグインのオブジェクト構文に関するビデオをご覧ください。
オブジェクト構文を使用する場合、プロパティは静的に解析されて、より最適化されたビルドが生成されます。そのため、実行時に定義しないでください。
たとえば、enforce: import.meta.server ? 'pre' : 'post'を設定すると、Nuxtがプラグインに対して行う将来の最適化が無効になります。 Nuxtは、オブジェクト構文を使用するときにフックリスナーを静的にプリロードするため、プラグインの登録順序を気にすることなくフックを定義できます。

登録順序

ファイル名に「アルファベット順」の番号をプレフィックスすることで、プラグインの登録順序を制御できます。

ディレクトリ構造
plugins/
 | - 01.myPlugin.ts
 | - 02.myOtherPlugin.ts

この例では、02.myOtherPlugin.ts01.myPlugin.tsによって注入されたすべてにアクセスできます。

これは、あるプラグインが別のプラグインに依存している場合に役立ちます。

「アルファベット順」の番号付けに慣れていない場合は、ファイル名は数値ではなく文字列としてソートされることに注意してください。たとえば、10.myPlugin.ts2.myOtherPlugin.tsの前に来ます。これが、例では1桁の数字に0をプレフィックスする理由です。

読み込み戦略

並列プラグイン

デフォルトでは、Nuxtはプラグインを順番に読み込みます。プラグインをparallelとして定義することで、Nuxtはプラグインの実行が終了するまで待機せずに次のプラグインを読み込むことができます。

plugins/my-plugin.ts
export default 
defineNuxtPlugin
({
name
: 'my-plugin',
parallel
: true,
async
setup
(
nuxtApp
) {
// the next plugin will be executed immediately } })

依存関係のあるプラグイン

プラグインが実行される前に別のプラグインを待つ必要がある場合は、プラグインの名前をdependsOn配列に追加できます。

plugins/depending-on-my-plugin.ts
export default 
defineNuxtPlugin
({
name
: 'depends-on-my-plugin',
dependsOn
: ['my-plugin'],
async
setup
(
nuxtApp
) {
// this plugin will wait for the end of `my-plugin`'s execution before it runs } })

コンポーザブルの使用

Nuxtプラグイン内では、コンポーザブルユーティリティを使用できます。

plugins/hello.ts
export default defineNuxtPlugin((nuxtApp) => {
  const foo = useFoo()
})

ただし、いくつかの制限と違いがあることに注意してください。

コンポーザブルが後で登録された別のプラグインに依存している場合、機能しない可能性があります。
プラグインは順番に、そして他のすべてよりも前に呼び出されます。まだ呼び出されていない別のプラグインに依存するコンポーザブルを使用する可能性があります。
コンポーザブルがVue.jsのライフサイクルに依存している場合、機能しません。
通常、Vue.jsコンポーザブルは現在のコンポーネントインスタンスにバインドされていますが、プラグインはnuxtAppインスタンスにのみバインドされています。

ヘルパーの提供

NuxtAppインスタンスでヘルパーを提供する場合は、プラグインからprovideキーの下で返します。

export default 
defineNuxtPlugin
(() => {
return {
provide
: {
hello
: (
msg
: string) => `Hello ${
msg
}!`
} } })

その後、コンポーネントでヘルパーを使用できます。

components/Hello.vue
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>

<template>
  <div>
    {{ $hello('world') }}
  </div>
</template>
グローバル名前空間の汚染を避け、メインバンドルエントリを小さく保つため、ヘルパーを提供する代わりにコンポーザブルを使用することを強くお勧めします。
プラグインがrefまたはcomputedを提供する場合、コンポーネントの<template>ではアンラップされません。
これは、Vueがテンプレートのトップレベルではないrefをどのように扱うかによるものです。詳細については、Vueのドキュメントをご覧ください。

プラグインの型付け

プラグインからヘルパーを返すと、自動的に型付けされます。useNuxtApp()の戻り値とテンプレート内で型付けされていることがわかります。

別のプラグイン*内*で提供されているヘルパーを使用する必要がある場合は、useNuxtApp()を呼び出して型指定されたバージョンを取得できます。ただし、一般的には、プラグインの順序が確実でない限り、これは避けるべきです。

高度なユースケースでは、次のように注入されたプロパティの型を宣言できます。

index.d.ts
declare module '#app' {
  interface NuxtApp {
    $hello (msg: string): string
  }
}

declare module 'vue' {
  interface ComponentCustomProperties {
    $hello (msg: string): string
  }
}

export {}
WebStormを使用している場合、この問題が解決されるまで、@vue/runtime-coreを増やす必要がある場合があります。

Vueプラグイン

Google Analyticsタグを追加するためにvue-gtagのようなVueプラグインを使用したい場合は、Nuxtプラグインを使用して行うことができます。

最初に、Vueプラグインの依存関係をインストールします。

npm install --save-dev vue-gtag-next

次に、プラグインファイルを作成します。

plugins/vue-gtag.client.ts
import VueGtag, { trackRouter } from 'vue-gtag-next'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueGtag, {
    property: {
      id: 'GA_MEASUREMENT_ID'
    }
  })
  trackRouter(useRouter())
})

Vueディレクティブ

同様に、プラグインでカスタムVueディレクティブを登録できます。

plugins/my-directive.ts
export default 
defineNuxtPlugin
((
nuxtApp
) => {
nuxtApp
.
vueApp
.
directive
('focus', {
mounted
(
el
) {
el
.focus()
},
getSSRProps
(
binding
,
vnode
) {
// you can provide SSR-specific props here return {} } }) })
Vueディレクティブを登録する場合、片側レンダリングのみに使用していない限り、クライアント側とサーバー側の両方で登録*する必要があります*。ディレクティブがクライアント側からのみ意味をなす場合は、~/plugins/my-directive.client.tsに移動し、~/plugins/my-directive.server.tsでサーバー用の「スタブ」ディレクティブを提供できます。
詳しくは Vue ドキュメントのカスタムディレクティブをご覧ください。