LoginSignup
1
0

More than 5 years have passed since last update.

Vue.jsで自動的にプラグインを読み込む

Last updated at Posted at 2019-03-08

概要

Vue.jsにおいてモジュールを作る上でpluginの仕組みを利用すると以下のような恩恵を受けることができます

  • モジュールをimportする必要がない
  • チーム等での作業の際にimportしたモジュール変数の名前がブレない
  • 関数内でvueインスタンスを取り扱える

このように便利なのでいつも僕は以下の画像のように大量にpluginを作ってます
(本当は数倍ありますが割愛しています)
image.png

しかし、このようにいっぱいpluginが増えてくるとapp.jsへ大量にVue.use(hoge)が増えますし、import文も盛り盛り増えます
そこでpluginフォルダ内に置かれたindex.jsを除くjsファイルを自動的にVue.useしてくれるように実装してみました

実装

WebpackのAPIを使います

plugins/index.js

import Vue from 'vue'
export default {
  install: function () {
    let modules = require.context('./', true, /.*\.[tj]sx?/)
    modules.keys()
      .filter(v => !v.match(/index/))
      .forEach(v => {
        let m = modules(v)
        Vue.use(m.default)
      })
  }
}

終わりです

解説

require.context

Webpackでフォルダ内の全ファイルを一気にrequireするに全てが載っていますが
Webpackのrequireにはrequrie.context1なるAPIが存在します

公式リファレンスから抜粋すると

require.context(directory, useSubdirectories = false, regExp = /^\.\//);

とあります
それぞれの引数は以下のようになります

directory

この関数が記述されているファイルからの相対パス、もしくは絶対パス

useSubdirectories

サブディレクトリを探索対象にするか否か

regExp

マッチさせたいファイル名の正規表現

context module API

require.contextによって返却される関数オブジェクトはresolve,keys,idの3つのプロパティを持ちます

resolve

module idとexportされたfunctionを返却します

keys

処理可能な全てのモジュールハンドルを返却します

id

Contextモジュールのidを返却します

ここではkeysを使い、index.jsを除くモジュールを全ての取り出します
説明には

処理可能な全てのモジュールハンドルを返却します

とありますが、実際にはファイル名の配列が返却されるので

modules.keys()
      .filter(v => !v.match(/index/))

のように簡単にfilterで除外できます
そして最後に

      .forEach(v => {
        let m = modules(v)
        Vue.use(m.default)
      })

してあげることでVueにpluginとして認識させることができます
ここでmodules(v)とありますが、modules自体が

A context module exports a (require) function that takes one argument: the request.

とあるようにrequireする関数なので、パス名を渡してあげるだけで大丈夫です

終わりに

現状Nuxt.jsだとnuxt.config.jsにプラグインのファイル名を記述しないと使えないという冗長さがあるので自動で取り込んで欲しいですね
PR投げるか

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0