【2018】Sass,webpack,styled-componentsなどCSS周りの環境・トレンドをまとめてみた

[DMM.com Advent Calendar 2018](https://qiita.com/advent-calendar/2018/dmm) 3日目の記事です。

オンラインサロンというWebサービスでサーバサイド/フロントエンドエンジニアをしている@yuzoohoです。
CSSを最近3ヶ月書いたのち、最近PHP7系/Reactを使うチームに移動しました。

# 今回この記事を書こうと思った理由
- 諸事情あって3ヶ月ほどCSSを書いてて色々なつらみがあった。
- 今の時代、ただの生のCSSを書いているところなんてそうそうないけど、何が流行りか分らない。
- CSS周りの環境がありすぎて何を使ったらいいか正直分からない。

# 想定読者
- CSS周りの環境が何があるか分からないから、とりあえずどんなものがあるのか知りたい。
- 各プリプロセッサやビルドツール・モジュールバンドラの概要をだいたい把握したい。


# CSSプリプロセッサ とは
CSSプリプロセッサと言われると「？」となるかもしれませんが、SassやLessといった普通のCSSでは書くことができない便利な書き方ができ、ビルドツールやタスクランナーを通してCSSにトランスパイルして使えるものになります。

**Googleトレンド比較（地域：日本、期間：2016年12/02〜2018年12/02）**
![css.png](https://qiita-image-store.s3.amazonaws.com/0/97496/455f3554-35c6-9e38-4bd5-0f97d81741e1.png)
※比較が5つまでなのと、CSS Moduleやstyled-componentsは若干異なる部類のものであるため除外しています。
※またPostCSS以外はCSS 〇〇とつけていますが、LessやStylusが本来あるべきワードとして計測されないためです。（Sassというワードで比較すると圧倒的にSassの動向が高いです。）

▼素直なキーワードでのトレンド
![css2.png](https://qiita-image-store.s3.amazonaws.com/0/97496/b9e66d31-57a6-f38e-15cc-60db4a1d07ff.png)
上記懸念点から、あまりどれがトレンドとは言いづらいのですが、圧倒的に**Sassが高い**のということは言えます。


## 各プリプロセッサ・フレームワーク・ライブラリの概要
Sass,Less,Stylus,PostCSSの他にCSS Modulesやstyled-componentsも入れました。

| 名前   |リリース時期　　　　|概要   |GitHubスター数|
|:-----------------|:------------------|:-------------------|:-------------------|
| Sass             |2006年  |一番ポピュラー。記法にSCSSとSASSがある。|11,602|
| Less             |2009年            |Sassに影響され当時持っていなかった機能を担うよう作られた。|15,835|
| Stylus           |2011年            |SassとLESSに影響を受けて作られたもの。|9591|
| PostCSS          |2013年|CSSツールを作るためのフレームワーク。 |19,765|
| CSS Modules|2015年|本来プログラミングにあるべき概念がCSSに取り込まれている。|11,012|
|styled-components|2016年|CSS in JS。ReactといったSPAと相性がいい。|20,650|
※GitHubのスター数は2018年12月2日現在

### Sass
2006年にリリースされてから、ずっと人気と言って良いであろうSass。記法は2種類あり、SCSS記法とSASS記法で、**SCSS記法**（セミコロンや括弧を書く書き方）が圧倒的に主流です。ネスト、変数、extend、mixin、演算などを使うことができる。

公式：https://sass-lang.com/
GitHub：https://github.com/sass/sass

### Less
Sassに影響され、後発として作られたのがLess、当初はSassが持っていない機能などを持っていた。変数スコープの概念などがあるが、Sassと若干変数の上書きなどの仕様が異なる。トレンドからもわかる通り、**現状流行は下火**。

公式：http://lesscss.org/
GitHub：https://github.com/less/less.js

### Stylus
Stylusは、ExpressやPug(Jade)を開発した人が開発した。SassとLessのいいところ取って作られており、また書き方的に`:`や`;`が省略可能。Sassと同じくif文、配列、for文などが使える。

公式：http://stylus-lang.com
GitHub：http://stylus-lang.com/

### PostCSS
Node.js製の**「CSSツールを作るためのフレームワーク**」。ベンダープリフィックスを自動で付与する「Autoprefixer」やリンターの「stylelint」などが有名。
SassやStylusの変数やネストなどは使うけど、mixinやextendは使わないといった場合には、PostCSSを使うと**必要な機能だけ選択**することができます。また、自分で作るのもよしという感じです。

公式：https://postcss.org/
GitHub：https://github.com/postcss/postcss

### styled-components
JSでstyleを記述するCSS in JSで、Reactのコンポーネント指向でフロントエンド開発が進む中、注目を集めているライブラリです。**ローカルスコープの概念**や**CSSそのものの記述は変わらない**、CSSとJSで値が共有できるなど便利な点がたくさんあります。

公式：https://www.styled-components.com/
GitHub：https://github.com/styled-components

### CSS Modules
CSS Modulesは、CSSのいい点を残しつつ、大規模化するCSSの問題点（グローバルネームスペース、依存性、デッドコード）を新しい機能追加によって解決しようと作られたものです。
CSSには今までなかった、**ローカルスコープの概念や、モジュールの単一責任、コンポジショ**ンなど、**本来プログラミングにあるべき概念**が取り込まれています。
SPAが流行ってきてコンポーネント指向になるなか、それに合わせてきたCSSといった言われようもあります。

GitHub：https://github.com/css-modules/css-modules



# ビルドツール・タスクランナー・モジュールバンドラ
プリプロセッサやCSS in JSなどを紹介してきましたが、上記のようなCSSを便利に書けるものを使っても、実際にCSSとして認識される書き方にトランスパイルし直す必要があります。

またCSSやJSを圧縮したい、ファイル管理を容易にしたいなど、そういった処理をプラグインを使って簡単に行えるようにということで、タスクランナーやモジュールバンドラが登場しました。

**Googleトレンド比較（地域：日本、期間：2016年12/02〜2018年12/02）**
![build.png](https://qiita-image-store.s3.amazonaws.com/0/97496/a0021144-7974-0643-b49b-bf744ffa1017.png)
2年前までは、gulpとwebpackが同じくらいでしたが、最近では圧倒的にwebpackの方がトレンドになってきてます。意外とParcelに注目がき始めているのもグラフからわかります。

## 各ビルドツール・タスクランナー・モジュールバンドラの概要

| 名前   |リリース時期　　　　|概要   |GitHubスター数|
|:-----------------|:------------------|:-------------------|:-------------------|
| gulp            |2013年|王道のビルドツールであったが最近は人気が下火になってきている。|30,624|
| webpack         |2012年|現在一番人気のモジュールバンドラである。gulpと併用することもある。|45,525|
| Grunt           |2011年|人気がなくなってしまったタスクランナー。|11,891|
| Parcel          |2017年|最近リリースされたばかりで注目が集まるモジュールバンドラ、configファイルがいらない。 |28,297|
| Rollup|2015年 |あまり馴染みのないモジュールバンドラ。|14,320|
※GitHubのスター数は2018年12月2日現在

### gulp
2年前ぐらいまでは、**王道のビルドツール**であったgulp。Node.jsをベースとしてできていて、基本的に非同期処理なのでGruntなどと比べると処理速度が早いのも特徴。
しかし、最近はgulpのプラグインが更新されていなかったり、node.jsのバージョンアップによって使えなくなったりなど、若干人気が落ちてきている印象です。

公式：https://gulpjs.com/
GitHub：https://github.com/gulpjs/gulp

### webpack
gulpよりもリリース時期は前ですが、**最近人気**でよく使われるようになってきているwebpack。SassをCSSにするには**sass-loader**というプラグインを使います。
gulpと併用されることもあり、CSSの圧縮にはgulp、JS周りのファイルの管理はwebpackなどといった使い分けの仕方もあるみたいです。

公式：https://webpack.js.org/
GitHub：https://github.com/webpack/webpack

### Grunt
GitHubのスター数でもわかるように最近はだいぶ人気がなくなってきてしまったGrunt。gulpよりも前にリリースされており、GruntもNode.js製で、grunt.initConfigでCSSの書き出しなどの各タスクの設定をJSON形式で指定します。
Gruntは、同期処理のため非同期処理のgulpに比べ**処理速度が遅い**です。

公式：https://gruntjs.com/
GitHub：https://github.com/gruntjs/grunt

### Parcel
2017年にリリースされたばかりで、ここ1年で注目を集め始めたParcel。webpackと**違い設定ファイルがそもそもない**ため、configファイルなどの肥大化などが起きにくいです。
Babel、PostCSS、Sass、Stylusなどはサポートしているため簡易的なものには使えそうですが、現状webpackにある機能でParcelにはない機能があるため、実務には不向きといった声もあります。

公式：https://parceljs.org/
GitHub：https://github.com/parcel-bundler/parcel

### Rollup
あまり馴染みのないRollupですが、webpackと同じくモジュールバンドラであり、プラグインを使えばSassやPostCSSなどもトランスパイルできます。ES2015を尊重する反面、モジュール分割ができない欠点もあるので大規模開発には向きにくいです。

公式：https://rollupjs.org/guide/en
GitHub：https://github.com/rollup/rollup

# 今後は使う言語やフレームワークによっても大きく変わってくるかも
ここまでCSSプリプロセッサやCSS in JS、ビルドツールやモジュールバンドラなどを一通り紹介しましたが、ReactやVueといったSPAフレームワークの流行、WebサービスやLPなどの開発用途の違いによって使うべきものが大きく変わってくるかもしれません。
一概にこれを使うべきとも言えず、どれが開発しやすいか、チームやサービスにもよると思います。


# 参考記事
- 各公式サイト・Github
- [SPAにおけるCSSについて、ひとつの解](http://yoshiko.hatenablog.jp/entry/css-in-js)
- [CSSモジュール ― 明るい未来へようこそ](https://postd.cc/css-modules/)
- [styled-componentsを使ったCSS設計](https://qiita.com/taneba/items/4547830b461d11a69a20)
- [PostCSS まとめ](https://qiita.com/morishitter/items/4a04eb144abf49f41d7d)
- [Parcel 入門 ～Parcelはwebpackの代わりになるのか～](https://qiita.com/soarflat/items/3e43368b2d767c730781)
- [webpack時代の終わりとparcel時代のはじまり](https://qiita.com/bitrinjani/items/b08876e0a2618745f54a)
- [Rollup v. Webpack v. Parcel](https://x-team.com/blog/rollup-webpack-parcel-comparison/)

上記記事参考にさせてもらいました。ありがとうございます。
※表記や解釈が間違っていた場合は、編集リクエストやコメントで教えてもらえると嬉しいです。