《Nuxt.js》Sassの共通の変数やmixinを一括で各コンポーネントに読み込む方法。

Nuxt.js を利用したプロジェクトで、sass のどこからでも利用したい mixin や変数などを、各コンポーネントで個別にインポートせずに一括で読み込みます。 vue-loader にオプションを渡せばいいのですが、nuxt.config.js から webpack の設定を変更するには、少しだけ工夫が必要です。

- [Nuxt.js - ユニバーサル Vue.js アプリケーション](https://ja.nuxtjs.org/)

導入は vue-cil でサクッと進めます。

```/.terminal

npx create-nuxt-app your-title

```

## パッケージのインストール

まず vue-loader で sass(scss) を解釈したいので、node-sass と sass-loader のパッケージをインストールします。

```/.terminal

yarn add --dev node-sass sass-loader

```

## nuxt.config.js の設定

nuxt.config.js に次のように記述します。

```nuxt.config.js

module.exports = {
  build: {
    extend (config) {
      /**
       * vue-loader に オプションを渡す
       */
      const vueLoader = config.module.rules.find(rule => rule.loader === 'vue-loader');
      const { options: {loaders} } = vueLoader || { options: {} }
      if (loaders) {
        for (const loader of Object.values(loaders)) {
          changeLoaderOptions(Array.isArray(loader) ? loader : [loader])
        }
      }
      config.module.rules.forEach(rule => changeLoaderOptions(rule.use))
    }
  }
}

/**
 * loader の名前一致でオプションをセットする
 */
function changeLoaderOptions(loaders) {
  if (loaders) {
    for (const loader of loaders) {
      let options;
      switch (loader.loader) {
        case 'sass-loader':
          options = {
            includePaths: [
              path.resolve(__dirname, './assets/sass/foundation/variable/'),
              path.resolve(__dirname, './assets/sass/foundation/mixin/')
            ],
            data: '@import "_variable";\n@import "_mixin";'
          };
          break
// 他の loader を追加できる
//        case 'stylus-loader':
//          options = {
//            includePaths: [path.resolve(__dirname, './assets/sass/')],
//            import: ['_import']
//          }
//          break
      }
      if (options) {
        Object.assign(loader.options, options)
      }
    }
  }
}

```

`config` の引数から vue-loader にアクセスして、`option` の `includePaths` にディレクトリ、 `data` に import したいファイルを渡します。
さらにこのコードでは stylus-loader など、Vue-loader の別の loader にもオプションが渡せるようにしています。

これで

```_variable.scss

$white: #fafafa !default;

```

と、用意した変数が、

```component.vue

<style lang="scss">

.ex {
  background-color: $white;
}

</style>

```

というふうにしてあげると、各コンポーネントで import せずに、利用できるようになります。


## Nuxt Style Resources で かんたんに読み込む

Nuxt Style Resources というモジュールを利用すると、先に紹介したようなコードを記述せずにシンプルに変数の読み込みを実装できます。(nuxt-sass-resources-loader は終了しました)

* https://github.com/nuxt-community/style-resources-module

```/.terminal

yarn add @nuxtjs/style-resources

```

```nuxt.config.js

module.exports = {
  modules: ['@nuxtjs/style-resources'],
  styleResources: {
   scss: [
    '~/assets/sass/foundation/variable/_index.scss',
    '~/assets/sass/foundation/mixin/_index.scss'
    ]
  }
}

```

というような感じで、手早く実装することができます。ちなみに、Nuxt Style Resources は LESS や Stylus にも対応しているので、同様の方法で必要なリソースを読み込むことができます。

基本はこの方法で実装する方が簡単だしお手軽だとは思いますが、一応 loader にどうやってオプションを渡すのかを理解しておくのも大切かなと思っています。


## アトミックデザインの atoms としての変数に

ぼくはここで読み込むような変数や mixin 群を、アトミックデザインの atoms として捉えていて、「components / molecules - organisms」「layouts - templates」「pages - pages」 というように、Nuxt.js のディレクトリ構成と紐づけることができるので、Nuxt.js はアトミックデザインにかなり接近したフレームワークだなあというところで、気に入っています。🍟


nuxt.config.js をうまく扱えるようになると、 Nuxt.js と仲良くなれるみたいなので、またまとめていきたいと思います。

おわります。