Nuxt.jsでCSSの設計を楽にする

vueファイルにどんどんCSSを書いていくと管理が大変です。
スコープを適用していれば問題無いですが、CSSファイルが一つのフォルダに纏められてないのは嫌だ！

そこで今回紹介するのは、`POSTCSS` + `ITCSS`を使った設計方法を`Nuxt.js`に適用するというものです。

## POSTCSS

![postcss.png](https://qiita-image-store.s3.amazonaws.com/0/104868/5087d3bf-aba0-1c7d-95c4-b17df8918e91.png)

`POSTCSS`はCSSツールを作るためのフレームワークです。様々なプラグインを使ってCSSに変更を当てると言うと簡単でしょうか。

sassみたいにネストして書けるプラグインや、ベンダープリフィックスを自動でつけてくれるプラグインなど多種多様です。

プラグインは自分で取捨選択できるため、プロジェクトごとにカスタマイズできることがメリットです！

詳しくは、[ここ](https://qiita.com/morishitter/items/4a04eb144abf49f41d7d)にわかりやすく解説されています。

## ITCSS

![Manage-Large-CSS-Projects-With-ITCSS.jpg](https://qiita-image-store.s3.amazonaws.com/0/104868/d75fa337-f4dd-5e4c-1fa3-c62dfc2da8c2.jpeg)

`ITCSS`はCSS methodology(方法論)の一つで、BEMやOOCSSなどもそこに含まれます。

* 多くの人にとって理解しやすい健全な環境
* 記述順とカスケードを管理すること
* 新旧問わず全てのルールセットが生きられる場所をつくること
* 無駄と重複を減らすこと
* 詳細度の戦いを終わらせること

というのをITCSSの論に則って書けば実現できるってやつです。
レイヤーごとに必要なCSSを書いていけばいい感じです。

これも詳しくは[こちら](https://qiita.com/makotot/items/2c3e99f15dca2789d403)を見ると理解できるとおもいます。

## 設計

どうやってITCSSの書くことができる環境をNuxt.jsで構築するかですが。

簡単にいうと、ITCSSのレイヤーごとにCSSファイルを分けて、元ファイルがCSSファイル群の読み込みを行います。
それ以外のファイルにはcssを書かないという感じ。

### 1. Nuxt.jsの構築

これはお好きにどうぞ。
今回は`vue-cli`からテンプレートを構築していきます。

[Nuxt.js を使ったスターターテンプレート - Nuxt.js](https://ja.nuxtjs.org/guide/installation#nuxt-js-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88)

```sh
$ vue init nuxt-community/starter-template <project-name>
$ cd <project-name>
$ npm install
$ npm run dev
```

### 2. PostCSSの設定

[Nuxt.jsのリファレンス](https://ja.nuxtjs.org/faq/postcss-plugins)では、`nuxt.config.js`にプラグインを羅列すると書いてありますが、今回こちらは使いません。
`postcss-loader`を使っていきます。

また、CSSファイル内でcssファイルを読み込むプラグイン、`postcss-import`も一緒にダウンロードしましょう。

```sh
$ npm i -D postcss-loader postcss-import
```

できたら、postcssの設定ファイルを書いていきます。
場所は`package.json`と同じルートディレクトリです。

```postcss.config.js
module.exports = {
  plugins: {
    'postcss-import': {}
  }
};
```

あと、`postcss-loader`の設定ですが、これは`nuxt.config.js`に書いていきます。


```nuxt.config.js
module.exports = {
  /*
   ** Headers of the page
   */
  head: {
    title: 'sample-project',
    meta: [{
        charset: 'utf-8'
      },
      {
        name: 'viewport',
        content: 'width=device-width, initial-scale=1'
      },
      {
        hid: 'description',
        name: 'description',
        content: 'A Special site of White Day'
      }
    ],
    link: [{
      rel: 'icon',
      type: 'image/x-icon',
      href: '/favicon.ico'
    }]
  },
  /*
   ** 最初の起点となるCSSを入力
   */
  css: [
    '@css/app.css'
  ],
  /*
   ** Customize the progress bar color
   */
  loading: {
    color: '#3B8070'
  },
  /*
   ** Build configuration
   */
  build: {
    /*
     ** Run ESLint on save
     */
    extend(config, {
      isDev,
      isClient
    }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })

        // ここ！！！！！
        // Add postcss loader for CSS files
        const cssLoader = config.module.rules.find((loader) => loader.test.toString() === '/\\.css$/')
        cssLoader.use.push('postcss-loader')
      }
    }
  }
}

```

**ここ！**って書いてあるところで、`postcss-loader`を設定しています。

あともう一つ設定するとこがあります。
それは、最初の起点となるCSSファイルの場所を宣言するものです。

```js
css: [
  '@css/app.css'
]
```

ここでは、ルートディレクトリにあるcssフォルダの`app.css`を指定してます。

### 3. CSSの設定

起点ができたわけですから、あとはITCSSに則って書くだけです。

以下のようなディレクトリを初期構成で作りました。
ITCSSのレイヤーごとにディレクトリを分けてます。

```
css/
├── app.css
├── base
├── components
├── generic
│   ├── generic.css
│   └── normalize.css
├── objects
├── settings
│   ├── color.css
│   └── font.css
├── tools
│   └── layout.css
└── trumps
```

元の`app.css`には以下のように書きます。
動作的には、レイヤーごとに上から読んでいます。

```css
/* Settings */
@import './settings/color.css';
@import './settings/font.css';

/* Tools */
@import './tools/layout.css';

/* Generic */
@import './generic/normalize.css';
@import './generic/generic.css';
```

動かして正常にCSSが読み込まれていたら完了です！お疲れ様でした！

## まとめ

ITCSSはあまり見慣れないですが、導入することでスッキリとしたCSSの開発ができるようになります！

みなさんもCSSの設計で迷っていいたらぜひ導入してみてください！

## 追記

私が紹介したのは、

* postcss-importでcssを読み込む
* nuxt.config.jsからrootのcssファイルを読み込む

ですが、

* Sassのimport機能を使う（コメント参照）
* App.vueやrootのvueファイルからcssファイルを読み込む

で実現可能とコメント欄で教えて頂きました！
ありがとうございますm(_ _)m

Sassか、PostCSSかお好みの方でお使いいただければと思います！