Nuxt.jsでSassの変数を使えるようにして全ページで読み込むようにする

## やりたいこと

* Nuxt.jsの環境でSassを使いたい
* CSSフレームワーク（Bulma）を導入したい
* 設定した変数をvueファイルで使いたい
* 共通スタイルcommon.cssみたいなファイルを全ページで読み込みたい

## 使うもの

* Bulma
* node-sass
* sass-loader
* nuxt-sass-resources-loader

## 作業内容

### ターミナルでインストール

```terminal
$ npm install sass-loader node-sass --save-dev
$ npm install bulma --save
$ npm install --save-dev nuxt-sass-resources-loader
```

### Sassファイルを作成する

* 変数を設定するファイル

```/assets/sass/variable.scss
// Import a Google Font
@import url('https://fonts.googleapis.com/css?family=Nunito:400,700');

// Set your brand colors
$purple: #8A4D76;
$pink: #FA7C91;
$brown: #757763;
$beige-light: #D0D1CD;
$beige-lighter: #EFF0EB;

// Update Bulma's global variables
$family-sans-serif: "Nunito", sans-serif;
$grey-dark: $brown;
$grey-light: $beige-light;
$primary: $purple;
$link: $pink;

// Update some of Bulma's component variables
$control-border-width: 2px;
$input-background-color: $beige-lighter;
$input-border-color: transparent;
$input-shadow: none;

// Import the rest of Bulma
@import "~/node_modules/bulma";
```

（Bulmaのサイトに載っているコードです。）

* 共通スタイル

```/assets/sass/common.scss
.title{
  position: relative;
  padding: 0.5em;
  background: $main;
  color: white;
  ::before {
    position: absolute;
    content: '';
    top: 100%;
    left: 0;
    border: none;
    border-bottom: solid 15px transparent;
    border-right: solid 20px $grey;
  }
}

.tooltip {
  position: relative;
  display: inline-block;
  margin: 1.5em 0;
  padding: 7px 10px;
  min-width: 120px;
  max-width: 100%;
  color: $text;
  font-size: $size-small;
  background: $info;
  &:before{
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    margin-left: -15px;
    border: 15px solid transparent;
    border-top: 15px solid $info;
  }
}

.position_center{
  position: absolute;
  top: 50%;
  left: 50%;
  transform : translate(-50%,-50%);
}
```

### `nuxt.config.js`に追記する

```nuxt.config.js
module.exports = {
  modules: [
    ['nuxt-sass-resources-loader', [
      '~/assets/sass/variable.scss',
    ]],
  ],
  css: [
    { src: '~/assets/sass/common.scss', lang: 'scss' },
  ],
};
```

これで、`やりたいこと`の内容はできるようになりました。


## ポイントを解説

### Nuxt.jsの環境でSassを使いたい

```terminal
$ npm install sass-loader node-sass --save-dev
```

これで、Sassをつかえるようにし、コンパイルしてくれます。
アプリケーションを再起動しなくても、自動的にコンパイルしてくれます。

Sassファイルは`/assets/`の中に作成します。

### CSSフレームワーク（Bulma）を導入したい

```terminal
$ npm install bulma --save
```

カスタマイズをせずに使う場合は、下記を`nuxt.config.js`に追記します。

```nuxt.config.js
module.exports = {
  css: [
    { src: '~/node_modules/bulma/bulma.sass', lang: 'sass' },
  ],
};
```

カスタマイズする場合は、カスタマイズ内容を書いたファイルの最後にBulmaを読み込みます。
（`nuxt.config.js`には、カスタマイズ内容を書いたファイルを読み込みます。）

```scss
@import "~/node_modules/bulma";
```

### 設定した変数をvueファイルで使いたい

```terminal
$ npm install --save-dev nuxt-sass-resources-loader
```

vueファイルで使いたい変数を設定したファイルを`nuxt.config.js`に追記します。

```nuxt.config.js
module.exports = {
  modules: [
    ['nuxt-sass-resources-loader', [
      '~/assets/sass/variable.scss',
    ]],
  ],
};
```
こうすることで、Sassファイルでもimportの記述なしで使うことができます。

### vueファイルでのSassの書き方

```menu.vue
<template>
  <ul>
    <li>メニュー1</li>
    <li>メニュー2</li>
    <li>メニュー3</li>
    <li>メニュー4</li>
  </ul>
</template>

<style lang="scss" scoped>
 ul, ol {
  padding: 0;
  position: relative;
}

ul li, ol li {
  color: $primary;
  border-left: solid 6px $primary;
  background: $grey-lighter;
  margin-bottom: 3px;
  line-height: 1.5;
  padding: 0.5em;
  list-style-type: none!important;
}
</style>
```

こんな感じで`style`要素に`lang`属性を設定するとSassが使えます。
`scoped`は、このファイル内のみにスタイルを適用したい時に使います。


### 共通スタイルcommon.cssみたいなファイルを全ページで読み込みたい

vueファイルで使いたい時にimportすれば使えるけれど、それでは毎回書かないといけないのでとてもめんどくさい。
そんな時は`nuxt.config.js`に書きます。

```nuxt.config.js
module.exports = {
  css: [
    { src: '~/assets/sass/common.scss', lang: 'scss' },
  ],
};
```

これで、各ファイルで指定しなくても、全ページでそのスタイルを当てられます。

### その他気をつけることなど

* `nuxt.config.js`の更新を反映するには、アプリケーションの再起動が必要です。
* `~`または`@`を使うことで、ルートにアクセスできます（[エイリアス-別名-](https://ja.nuxtjs.org/guide/directory-structure#%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9-%E5%88%A5%E5%90%8D-)）
* vueファイルの`style`で`assets`の中を指定するときは`~assets/...`とする


## 参考

* [Bulma](https://bulma.io/)
* [NUXT.JS 入門 #5 – NUXT.JS と CSS の管理](https://www.chatbox.blog/2018/05/02/nuxt-js-5/)
* [Nuxt.jsにおいてSCSSを使う方法(とその依存ライブラリについて)](https://morimori-singing-engineer.hatenablog.com/entry/2018/06/21/223242)
* [Nuxt.jsでSCSSの変数をvueファイルでも使えるようにする](https://blog.cntlog.net/archives/3431)
* [Nuxt.jsにBulmaを導入して変数を使ったカスタマイズを行う](https://qiita.com/mnmemo/items/5eb4fb8cbfe17670fd36)


## 2018.12.11 追記

```scss
@import "~/node_modules/bulma";
```

の記載場所について、
`variable.scss`の最後に書くと、2回読み込まれるなど優先度が高くなり、変数ではなく直接数値で指定してあるものを上書きすることが難しくなってくる。

`common.scss`の1行目に書いたほうが、扱いやすいかもしれない。

## 2019.5.16 追記

「nuxt-sass-resources-loader」はNuxt.js 2.4.0以降サポート終了したみたいです。

バージョンあげたら大変なことになった。。。
「@nuxtjs/style-resources」が強く推奨されているらしいので、これを使って解決しました。

参考サイト
https://qiita.com/tsukue/items/e3565d889ebe7b078748