Plugins - アプリ全体への機能注入

ロードマップ: Vue.js学習ロードマップ

What(何についてか)

Plugin は、Vue アプリ全体に対して機能を追加する自己完結した初期化単位 である。 導入は app.use(plugin, options) で行う。

import { createApp } from 'vue'
 
const app = createApp({})
app.use(myPlugin, {
  /* optional options */
})

plugin は次のいずれかで定義できる。

  • install(app, options) メソッドを持つ object
  • install 関数そのものとして振る舞う function
const myPlugin = {
  install(app, options) {
    // app-level setup
  }
}

本質的には、app instance を受け取ってアプリ全体の設定や拡張を行う仕組み である。

Why(なぜ必要か)

component や composable は、主に局所的な UI やロジックの再利用を担う。 一方 plugin は、より上位の app レベルの横断的セットアップ をまとめるために使う。

代表的には以下のような場面で有効である。

  • アプリ全体で使う共通 API の注入
  • global component / custom directive の一括登録
  • provide / inject による app-wide dependency の配布
  • ライブラリとして複数の初期化処理を束ねて提供する

つまり plugin は、複数 component にまたがる共通基盤を「起動時に 1 回だけ構成する」ための仕組みである。

How(どう動くか)

基本構造

app.use(plugin, options) を呼ぶと、plugin の install(app, options) が実行される。 options には導入側が与えた設定オブジェクトがそのまま渡る。

const myPlugin = {
  install(app, options) {
    // options を使って app を拡張する
  }
}

plugin の中でよく行う処理は以下である。

  • app.component() で global component 登録
  • app.directive() で global custom directive 登録
  • app.provide() で app 全体に依存注入
  • app.config.globalProperties に global property / method 追加

globalProperties を使った API 注入

公式は簡易 i18n plugin を例に、アプリ全体から使える $translate() を追加している。

export default {
  install: (app, options) => {
    app.config.globalProperties.$translate = (key: string) => {
      return key.split('.').reduce((o: any, i: string) => {
        if (o) return o[i]
      }, options)
    }
  }
}

導入側は翻訳辞書を app.use() の第 2 引数として渡す。

app.use(i18nPlugin, {
  greetings: {
    hello: 'Bonjour!'
  }
})

その結果、template では次のように使える。

<h1>{{ $translate('greetings.hello') }}</h1>

この設計のポイントは、plugin が 設定を受け取り、共通 API を構成し、app 全体へ公開する という責務を持つ点にある。

provide / inject を使った依存注入

plugin は global method を増やすだけでなく、app.provide() によって app-wide dependency を配布できる。

export default {
  install: (app, options) => {
    app.provide('i18n', options)
  }
}

利用側 component は inject() で受け取る。

<script setup lang="ts">
import { inject } from 'vue'
 
const i18n = inject<any>('i18n')
console.log(i18n.greetings.hello)
</script>

この方式では、依存関係が component 側コードに明示される。 そのため、globalProperties よりも出どころが追いやすい場合が多い。

globalPropertiesprovide / inject の使い分け

両者は似ているが、役割が少し異なる。

  • globalProperties

    • template や instance から直接使える
    • 利用側の記述量が少ない
    • 暗黙的で増やしすぎると追跡が難しい
  • provide / inject

    • 依存関係がコード上に明示される
    • <script setup> と相性が良い
    • 設定オブジェクトや共有資源の配布に向く

実務上は、関数やメソッドをアプリ全体へ露出したいなら globalProperties、共有資源や設定を注入したいなら provide / inject という整理がしやすい。

Plugin の責務範囲

Plugin は便利だが、影響範囲が app 全体に及ぶ。 そのため、局所的な問題まで plugin に押し込むのは避けるべきである。

以下のように役割を切り分けると設計が安定する。

flowchart TD
    A["再利用・共有したい対象は何か"] --> B["特定画面の UI"]
    A --> C["状態や副作用ロジック"]
    A --> D["アプリ全体の基盤機能"]
    B --> E["Component"]
    C --> F["Composable"]
    D --> G["Plugin"]

plugin は、アプリ全体の基盤機能や横断的セットアップ に限定して使うのが自然である。

実務上の注意

Global な影響を持つ

plugin は app レベルで 1 回導入されるため、影響範囲が広い。 そのため「便利だから全部 global にする」という設計は危険である。

特に app.config.globalProperties は、増やしすぎると以下の問題を招く。

  • どこから生えた API なのか分かりにくい
  • 別 plugin との衝突や責務曖昧化が起こりやすい
  • app 固有の前提が template 全体へ漏れやすい

公式も global properties の使いすぎは避けるよう注意している。

Plugin は初期化コードの束

plugin 自体は日常的な UI 実装の主役ではない。 普段の component 開発では、plugin が用意した基盤を利用する側になることが多い。

そのため、Vue 初学段階では「plugin を多用する」よりも、 router や i18n など既存 plugin をどう使うかを理解し、必要なら自前で app-level setup を束ねられる 程度の理解で十分実務に耐える。

Options API → Composition API 差分(補足)

項目従来の見方Vue 3 / Composition API 時代の見方
アプリ全体への共通機能追加instance 拡張や global mixin に寄りがちapp.use() と plugin で初期化を明示化
共通 API の配布this.$xxx へ直接追加しがちglobalProperties は限定的に、共有資源は provide/inject を活用
再利用の粒度component / mixin に詰め込みやすいapp-level の責務だけ plugin に分離
<script setup> との相性this 依存が残りやすいinject() ベースの方が自然に書ける

Key Concepts

用語説明
PluginVue アプリ全体へ機能を追加する初期化単位
app.use()plugin を app に導入する API
install(app, options)plugin の本体となる初期化関数
app.config.globalProperties全 component instance から参照可能な global property / method 置き場
app.provide()app 全体に依存や設定を注入する API
inject()provide された依存を component 側で受け取る API
App-level Setupアプリ起動時に 1 回だけ行う横断的初期化

実務での判断軸

  • 特定画面の UI を再利用したいなら component を使う
  • 状態や副作用ロジックを再利用したいなら composable を使う
  • app 全体にまたがる基盤機能や初期化をまとめたいなら plugin を使う
  • globalProperties は便利だが乱用しない
  • <script setup> 中心の開発では、共有資源配布は provide / inject の方が見通しを保ちやすい

Plugin は Vue アプリの土台を構成するための仕組みであり、component や composable より一段上のレイヤーを扱う。したがって、局所ロジックではなく「アプリ全体で一貫して必要な機能」に対して使うのが適切である。