PostCSS 実践

[PostCSS 入門](https://qiita.com/ohnaka0410/items/47269ce5ed6e87eb0ff6)の続きです。

実際に開発で利用できるPostCSSの環境をnpm-scriptsで作成していきます。

## 作成する環境の仕様
- PostCSSを利用する。（脱Sass）
- npm-scriptsを利用する。（依存モジュールを減らすため、webpackやgulpは利用しない）
- srcフォルダ内の.pcssファイルをを変換し、publicフォルダに.cssファイルを出力する。
- サブモジュールはファイル名のプレフィックスに`_`をつける。
- 開発用ビルドは、ファイルの変更を検知し自動的に再ビルドを行う。
- 開発用ビルドは、ソースマップを出力する。（本番用ビルドでは出力しない。）

## 環境の確認
```bash
$ node -v
v12.13.0
$ npm -v
6.13.6
```
## プロジェクトの作成
```bash
$ npm init -y
```
```json:package.json
{
  "name": "PostCSS-Boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

## PostCSSのインストール
```bash
$ npm i -D postcss-cli
```

<details><summary>package.jsonの差分</summary><div>

```diff:package.json
{
  "name": "PostCSS-Boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
-   "license": "ISC"
+   "license": "ISC",
+   "devDependencies": {
+     "postcss-cli": "^7.1.0"
+   }
}
```

</div></details>

## PostCSSプラグインの追加

### postcss-import
```bash
$ npm i -D postcss-import
```

<details><summary>package.jsonの差分</summary><div>

```diff:package.json
{
  "name": "PostCSS-Boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
-     "postcss-cli": "^7.1.0"
+     "postcss-cli": "^7.1.0",
+     "postcss-import": "^12.0.1"
  }
}
```

</div></details>

複数のファイルを1つに結合するためのモジュール。

### postcss-preset-env
```bash
$ npm i -D postcss-preset-env
```

<details><summary>package.jsonの差分</summary><div>

```diff:package.json
{
  "name": "PostCSS-Boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "postcss-cli": "^7.1.0",
-     "postcss-import": "^12.0.1"
+     "postcss-import": "^12.0.1",
+     "postcss-preset-env": "^6.7.0"
  }
}
```

</div></details>

将来ブラウザで実装される可能性がある機能(変数など)を利用できるモジュールのプリセット。

### postcss-flexbugs-fixes
```bash
$ npm i -D postcss-flexbugs-fixes
```

<details><summary>package.jsonの差分</summary><div>

```diff:package.json
{
  "name": "PostCSS-Boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "postcss-cli": "^7.1.0",
+     "postcss-flexbugs-fixes": "^4.1.0",
    "postcss-import": "^12.0.1",
    "postcss-preset-env": "^6.7.0"
  }
}
```

一部のFlex Boxのバグ(主にIE)にハマらないように自動修正してくれるプラグイン。

</div></details>

## 設定ファイルの作成

### PostCSSの設定ファイルの作成

```js:.postcssrc.js
/**
 * PostCSS Config
 */
module.exports = (ctx) => {
  return {
    map: ctx.options.map,
    plugins: {
      'postcss-import': {
        /**
         * @module postcss-import
         * @url https://www.npmjs.com/package/postcss-import
         * --------------------------------------------------------- */
      },
      'postcss-preset-env': {
        /**
         * @module postcss-preset-env
         * @url https://www.npmjs.com/package/postcss-preset-env
         * --------------------------------------------------------- */
        stage: 3,
        features: {
          'nesting-rules': true,
        },
        autoprefixer: {
          /**
           * @module autoprefixer
           * @url https://www.npmjs.com/package/autoprefixer
           * --------------------------------------------------------- */
          cascade: false,
          grid: 'autoplace',
        },
      },
      'postcss-flexbugs-fixes': {
        /**
         * @module postcss-flexbugs-fixes
         * @url https://www.npmjs.com/package/postcss-flexbugs-fixes
         * --------------------------------------------------------- */
      }
    },
  }
}
```

### Browserslistの設定ファイルの作成

```:.browserslistrc
last 2 versions, not dead
```

## npm-scriptsの作成

```diff:package.json
{
  "name": "PostCSS-Boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
-     "test": "echo \"Error: no test specified\" && exit 1"
+     "prod": "postcss \"./src/**/!(_)*.pcss\" --base \"src\" --dir \"public\" --ext css --no-map",
+     "dev": "postcss \"./src/**/!(_)*.pcss\" --base \"src\" --dir \"public\" --ext css --watch"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "postcss-cli": "^7.1.0",
    "postcss-flexbugs-fixes": "^4.1.0",
    "postcss-import": "^12.0.1",
    "postcss-preset-env": "^6.7.0"
  }
}
```

## npm-scriptsの実行

### 開発用ビルド+変更監視
```bash
$ npm run dev
```

### リリース用ビルド
```bash
$ npm run prod
```

## 最後に
しばらく使ってみて、良いモジュールがあれば随時更新していきます。
また、追加で表示確認用にbrowser-sync、リンターにstylelintも合わせて利用すれば、さらに快適に開発が進められます。

おすすめ設定
　→ [PostCSSのおすすめ設定](https://qiita.com/ohnaka0410/items/9128839ac02487cfbfb4)