概要
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.context
1なる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投げるか