概要
Vue.jsにおいてモジュールを作る上でpluginの仕組みを利用すると以下のような恩恵を受けることができます
- モジュールをimportする必要がない
- チーム等での作業の際にimportしたモジュール変数の名前がブレない
- 関数内でvueインスタンスを取り扱える
このように便利なのでいつも僕は以下の画像のように大量にpluginを作ってます
(本当は数倍ありますが割愛しています)

しかし、このようにいっぱい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投げるか