Rails & Webpacker環境でPostCSSを使う

# はじめに
Rails & Webpackerの環境でPostCSSで書かれたCSSを取り込もうとした時に、そもそもPostCSSってRailsでどう扱うんだっけ？？となって少し詰まったのでその時の対応についてになります。

# 環境
- rails: 6.0.0
- webpacker: 4.0.7

# PostCSSって
[ぼちぼちPostCSSの勉強をやっちゃいますか](https://qiita.com/yuyake0084/items/301b716214e0352360c5) から
> PostCSSはNode.js製のモジュールでCSSをコンパイルできるツールです。
そうなんです。LessやSassとは異なり、CSS拡張子をソースとして新しいCSSを生成してくれるんです。

またこちらの記事に詳しくまとめられています。ありがたい！
[PostCSS まとめ - Qiita](https://qiita.com/morishitter/items/4a04eb144abf49f41d7d) 

# やりたいこと
Webpackerで管理しているCSSをPostCSSで書いてコンパイルする

# 結論
先に結論から言うと、RailsでWebpackerをインストールするとv4以上ではアプリケーションのルートディレクトリに `postcss.config.js` （Webpackerのv4より前は.postcssrc.yml）が生成されます。
このファイルは以下のような内容になっていて`postcss-import`、`postcss-flexbugs-fixes`、`postcss-preset-env`は何もしなくてもデフォルトで使えるようになっています。

```js:postcss.config.js
module.exports = {
  plugins: [
    require('postcss-import'),
    require('postcss-flexbugs-fixes'),
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
}
```

**他のPostCSSプラグイン**を使いたい場合は以下の流れで追加できます。

- 使いたいPostCSSライブラリをyarn（or npm）で追加
- postcss.config.jsを修正


# 使用例
簡単な例で説明していきます。

## WebpakcerでCSSを扱う
PostCSSの前にWebpakcerでCSSを管理する環境の準備です。
以下のような構成になっているとして

```
app/javascript:
  ├── packs:
  │   # only webpack entry files here
  │   └── application.js
  └── css: <-- 追加
      └── application.css <-- 追加
```

webpackのエントリーファイルからcssをimport

```js:app/javascript/packs/application.js
import '../css/application.css' <-- 追加
```

これで準備完了です。
`bin/webpack` を実行すると `application.css` がコンパイルされるようになります。

## PostCSSプラグイン追加
試しに[postcss-nested](https://github.com/postcss/postcss-nested)を追加してみます。

> PostCSS plugin to unwrap nested rules like how Sass does it.

とあるようにpostcss-nestedを使うとsassのような書き方でネストしたcssを書くことができます。

では簡単なcssで確認していきます。

```css:app/javascript/css/application.css
.hoge {
  &_title {
    font-size: 50px;
  }
}
```

プラグイン追加前の状態でコンパイルして出力されたファイルを見ると`&_title`がそのまま出力されてしまいます。

```sh
$ bin/webpack

# 出力されたファイルを見ると&_titleがそのままになっている
# ".hoge {\n  &_title {\n    font-size: 50px;\n  }\n}\n"
```

### yarn add
プラグインを追加していきます。

```sh
$ yarn add -D postcss-nested
```

### postcss.config.jsを修正

```js:postcss.config.js
module.exports = {
  plugins: [
    require('postcss-import'),
    require('postcss-flexbugs-fixes'),
    require('postcss-nested'),  <-- 追加
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
}
```

### コンパイルして確認

```sh
$ bin/webpack

# コンパイルされたファイルを確認（デフォルトの設定の場合は public/packs/js 以下に出力される）
# ".hoge_title {\n    font-size: 50px;\n  }\n"
```
無事`.hoge_title`の形に変換されていることが確認できました。
 

# まとめ
以上、Webpackerで`postcss.config.js`でPostCSSを使う時の流れでした。
普段CSS周りをさわっていないと環境から作ろうとして、そもそもどうなってるんだっけとなってしまったので、たまには環境作ってざっくりでも把握しておこうと思いました。

## 参考にした記事
- [Keeping your babel and postcss config up to date in Rails 6](https://medium.com/comix-life/keeping-your-babel-and-postcss-config-up-to-date-in-rails-6-f2b258d0573d)
- [postcss-preset-envでpostcss-nestingを使う - Qiita](https://qiita.com/Statham/items/036dcf71811b043626f8)
- [ぼちぼちPostCSSの勉強をやっちゃいますか](https://qiita.com/yuyake0084/items/301b716214e0352360c5) 
[PostCSS まとめ](https://qiita.com/morishitter/items/4a04eb144abf49f41d7d)
- [PostCSS まとめ - Qiita](https://qiita.com/morishitter/items/4a04eb144abf49f41d7d)