Dark

Nuxt.jsで*.global.vueと名付けておくとグローバル登録してくれるプラグイン

*.global.vueと名付けたコンポーネントを、全てのコンポーネントから呼べるように自動でグローバル登録してくれる便利プラグインの紹介です。nuxt/nuxtjs.orgで使われていました。

コード

2つのファイルからなります。

  • global-components.plugin.js
    • プラグイン本体
  • index.js
    • global-components.plugin.jsをプラグインに登録するモジュール

global-components.plugin.js

import Vue from 'vue'
<% options.globalComponents.forEach(({ name, path }) => { %>import <%= name %> from '<%= path %>'
<% }) %>

<% options.globalComponents.forEach(({ name }) => { %>Vue.component(<%= name %>.name || '<%= name %>', <%= name %>)
<% }) %>
  

(コードはglobal-components.plugin.jsより)

プラグイン本体です。lodash template(テンプレートプラグインあたりを参照)で記述されています。例えば、以下の様なglobalComponentsを与えると、コンポーネントをグローバル登録するjsファイルが出力されます。

lodash_template_sample

次のindex.jsは、このglobalComponentsを作り、global-components.plugin.jsaddPlugin()でプラグインに登録する処理をします。

index.js

const { join, basename } = require('path')
const globby = require('globby')

export default async function () {
  const { options } = this.nuxt

  const dir = options.dir.components || 'components'
  const componentsDir = join(options.srcDir, dir)

  let globalComponents = await globby('**/*.global.(vue|js)', {
    cwd: componentsDir,
    asbsolute: true,
    onlyFiles: true
  })
  globalComponents = globalComponents.map((path) => {
    return {
      name: basename(path).replace(/\.global\.(vue|js)$/, ''),
      path: `~/${dir}/${path}`
    }
  })

  this.addPlugin({
    src: join(__dirname, 'global-components.plugin.js'),
    options: {
      globalComponents
    }
  })
}

(コードはindex.jsより、コメントを削除したもの)

index.jsはビルド専用モジュールです。thisにはModuleContainerインスタンスが入っています。this.addPlugin()で先ほどのglobal-components.plugin.jsplugins[]オプションの先頭に追加します。

使い方

modulesディレクトリ(なければ作る)にglobal-componentsのようなディレクトリを作り、先程の2つのファイルを置きます。

.
├── global-components
│   ├── global-components.plugin.js
│   └── index.js

そして、このモジュールをnuxt.config.jsに登録します。

  buildModules: [
    '~/modules/global-components/',
  ],

globbyが入ってなければ入れておきます。

yarn add -D globby

これだけです。試しに使ってみましょう。

新規Nuxtプロジェクトを作成し、以下のMyButton.global.vueを作成します。

<template>
  <button>global button</button>
</template>
<script>
export default {
  name: "MyButton"
};
</script>

これを、以下のようにindex.vueで使ってみます。明示的にimportしていないところがポイントです。

<template>
  <div class="container">
    <my-button />
  </div>
</template>

<script>
export default {
}
</script>

結果、ちゃんと使えました。

global_components_sample

おわり

コンポーネントをimportして、export default { components: ... }で登録する手間が省けるので、リファクタリングの一手法として便利です。

Share:
記事一覧
Dark