Magento2のスタイル（LESS）変更の方法概要

本記事は[Magento Advent Calendar 2015](http://www.adventar.org/calendars/931)の9日目の記事になります。

← 8日目[Magentoでアクセス集中を乗り切るには〜後編〜](https://principle-works.jp/blog/how-to-survive-magento-access-peak-part2/)
10日目[Magentoで納品書のレイアウトを変更する](http://qiita.com/macseto/items/709d0f715b5d714cf78a) →

年末進行作戦行動中の新兵＠Magento日本コミュニティ、@kzkiq2ndです。いつでも必死です。

[西軍曹](https://twitter.com/hirokazu1225)とこつこつと進めているMagento2の日本語化ですが、今月中には[日本語化モジュール@Magento日本コミュニティ版](https://github.com/Magento-Japan/m2-japaneselocale)が形になりそうな雰囲気です。翻訳中は管理画面などしっかり見ていくわけですが、「こんなオプションあるんだナァ」「これは作り込んでるワ」という発見も多くなかなか楽しくやっております。管理画面の解説はまたそのうち。

さて、本日の話題はMagentoでのLESSです。

## LESS

新版Magento2の面白い設計の一つに、LESSを利用している点があります。もちろん、ただLESSを使うだけではなく`import`の機能を利用してモジュール毎、パーツ毎にLESSを定義し、後述する用意されたコンパイルオプションを使って一つにまとめる、という方式がデフォルトになりました。

↓`Magento UI library`としてデフォルトで定義されているLESSの構成（[githubリンク](https://github.com/magento/magento2/tree/2.0.0/lib/web/css))
<img width="271" alt="スクリーンショット 2015-12-10 10.32.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/752/d0a13a60-4bab-71bf-6f84-70fccfad9212.png">

ズラズラとならんでいますが開発にはこれらを使う前提になります。

まず全体の設計を俯瞰すると、Magento2テーマにおけるスタイルとは、`Magento UI library`のスタイル + モジュール用のLESS + 独自スタイルという積み上げ形式になります。あくまで上書きしながら積み上げるイメージで、つまり開発用`blank`テーマをベースに切った張ったするしか道はないという意味で、Magento1以上に事前に頭のなかで継承・上書きイメージを思い描く必要があります。特にデザインカンプ式開発フローを採用している場合は、円滑な進行のためにフロントエンドエンジニアから早めの口出しが求められるシステムと言えます。

スタイルにおける基礎部分は`Magento UI library`のLESSが担っています。Magento2のドキュメントの気合いのいれっぷりはここにも表れており、アプリケーション内にもREADMEと各UIパーツ用ドキュメントを配置してあります。本記事では詳しく触れませんが、[こんな感じです。](https://github.com/magento/magento2/blob/2.0.0/lib/web/css/docs/source/README.md)

なお、一応CSSも同じようにルールに乗っている限りはバラバラに配置してもまとめてくれるのですが、`Magento UI library`もデフォルトモジュールもLESSを基本的に利用しています。開発者側から見れば細切れになったLESSが散らばっている状態にはなりますが、逆に言えばファイル単位で分けられているが故に用意されたルールの上を歩くならばスタイル汚染が広がりにくく、Git管理にも多少わかりやすく、利用していないモジュールのLESSは読み込まない、上書きも最小限でOK、モジュールにLESSを含めることができるのでモジュール新規追加時も快適という、3のメリットがあるならば1のデメリットは捨て置く感じのMagentoらしい方向性の設計です。

↓`blank`テーマで定義されているモジュール用のLESS
<img width="262" alt="スクリーンショット 2015-12-10 10.23.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/752/781ecd18-2547-15ef-7e00-9622662135a5.png">

このディレクトリ構造もルールに基づいています。ヘビー。

## LESSコンパイルオプション

デフォルトで用意されたコンパイルオプションは、

0. サーバーサイドでコンパイルしてCSSで配布する__プロダクションモード__（Magentoキャッシュ運用と同等）
0. クライアント向けLESSコンパイラーであるLESS.jsを利用した__デベロッパーモード__（常に`.less`ファイルを配布しブラウザ側でコンパイル。__ただしなんか安定しない__）
0. Grunt.jsを利用したCLIでのコンパイル（任意のタイミングで実行可能）

となり、__「こんだけオプション用意したんだから、十分使えるでしょ？」__という自信がドキュメントから透けて見える感じの仕上がりです。主に使われるだろうプロダクションモードとデベロッパーモードは、管理画面もしくは`bin/magento`コマンドで切り替えが可能になります。

デベロッパーモードは全ての`.less`をそのまんま配信してブラウザ上でコンパイルするというモードになり、Magento1から続く__「開発者はキャッシュを切るところから始めるけれど、それをするとむちゃくちゃアプリが重いつらいねむい」__という開発スタイルにおいては、スタイル編集時にもある程度の軽さと、LESSコンパイルを待たないで即時反映の便利さがあります。（__ただしなんか安定しない__）

翻訳のためにアプリケーションをさわっている限りでは、アプリが後ろで何しているのかあまり意識せずとも

- 開発者モードなら即時反映
- プロダクションモードならキャッシュが効く

だけ理解すれば使えるというのは、Magentoの開発者向け設計としては珍しくハードルが低くなったポイントです。もちろん自分でGruntファイルを改造すればなんでもできるのでしょうが、基本的には用意されているモードを使えば`Gulp vs Grunt`戦争（最近聞きませんね）など、開発の本筋ではないが決めないと始まらないポイントを回避できる＆スクリプト用意しなくてよいのはナイスです。

ところで、CSSプリプロセッサ三兄弟SASS（2006）・LESS（2009）・Stylus（2010）の次男のLESSを採用したいきさつは諸説考えられますが、これら3兄弟、日本国内では確か当時熱量がすごかったJSゲーム実装界隈から採用が広まった2011年頃から流行りだし、その後いくつかの「どれをつかうか」議論もあった印象ですが、2015年の今となっては兄弟どれもほとんど同じなのでフロントエンド開発者としてはLESSで特に文句はないはずです。むしろLESS.jsとかいう飛び道具が普通に搭載されているワークフローにMagentoらしさというか、味わいを感じるポイントになっています。（__そしてなんか安定しない__）

## スタイルの編集の概観
Magento2の標準テーマの一つ`blank`を継承した子テーマでカートボタンの色を上書きする手順を紹介します。ここで紹介するものは基本的に[公式DevDocs](http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/css-topics/css-overview.html)の内容なので、本記事の立ち位置はオマケつきの意訳です。

それと「子テーマの作りかた」の知識が別途必要なので、ここでの解説は__あくまで手順の紹介__です。「コピペでできる〜」とかではないです。

デフォルトのボタン色を
<img width="400" alt="スクリーンショット 2015-12-09 22.49.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/752/6f02dd81-ea59-c499-7353-46dd901973ce.png">

こうします。
<img width="400" alt="スクリーンショット 2015-12-09 23.35.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/752/2f82226e-2ac1-7248-ab88-ad114705042e.png">

しかしすごください服ですねコレ。

### Step0. 前提知識：継承・上書き
Magentoの開発者向け設計の根幹にある概念__「継承・上書き」__が勿論でてきます。コレに関してはMeet Magento Japan 2015でお話したり、Magento1の内容として前回のアドベントカレンダー記事にもちょっと書いていますので、必要あれば[そちら](http://qiita.com/kzkiq2nd/items/9d420754db3f341fe1fd)を参照してください（そのうちきっちりまとめるつもりもあります）

### Step1. 子テーマを作る
まずは親テーマ`blank`を継承した子テーマ`OrangeCo/orange`をつくります。子テーマの作成にも作法がありますが、いまのところは「子テーマをつくる」という理解で進めます。

子テーマ`orange`に最低限必要な構成
<img width="400" alt="スクリーンショット 2015-12-09 22.45.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/752/aa11cfb3-70ee-dde7-4407-1a8462c6ead1.png">


子テーマの作法に関する公式のDevDocsは[こちらからどうぞ](http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/themes/theme-create.html)。

### Step2. 上書き.lessを作る
子テーマ`OrangeCo/orange`は設定された親テーマ`Blank`のLESSを全て継承していますが、__ファイルの位置と名前__によって子テーマのファイルが最優先で読み込まれ、この解説の場合`Blank`のLESSを__部分的に上書き__します。

__ファイルの位置と名前__ルールは相変わらず、というかM2でさらに細かくなっていますが、この解説では以下の位置にLESSを追加します。

`app/design/frontend/OrangeCo/orange/web/css/source/_theme.less`

ルールはたくさんありますが、上記の位置に`_theme.less`を配置すると、`lib/web`以下にあるデフォルトLESS変数を上書きできます。

<img width="400" alt="スクリーンショット 2015-12-09 23.36.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/752/46bf95a1-0351-7bd3-37bd-b3ce679e1386.png">
一つファイルを追加するためにたくさんディレクトリが必要


### Step3. LESSを編集する
`app/design/frontend/OrangeCo/orange/web/css/source/_theme.less`

に変数、

```
//  Primary button
@button-primary__color: @color-white;
@button-primary__hover__color: @color-white;
@button-primary__background: @color-orange-red1;
@button-primary__hover__background: @color-orange-red4;
@button-primary__border: 1px solid @color-orange-red2;
@button-primary__hover__border: 1px solid @color-orange-red2;
```

を書いて保存する。ここでは全て変数に変数を当てはめていますが、これらはすべて`Magento UI library`にデフォルトで設定されている変数定義を使っています。

### Step4. テーマを適用し、キャッシュを更新する
#### 1. 作った子テーマ`Orange`をまず適用します。
管理画面で「店舗」>「設定」>「デザイン」>「デザインテーマ」で`Orange`を選び、「設定を保存」します。

![Screen Shot 2015-12-09 at 22.45.13.png](https://qiita-image-store.s3.amazonaws.com/0/752/8421873e-46a3-11b6-c9f1-8cb4c4c87925.png)

#### 2. キャッシュを更新します。
Magento2が自動的に更新が必要なことを教えてくれますが、
管理画面で「システム」>「キャッシュ管理」>「キャッシュストレージをリフレッシュする」を選び、キャッシュを更新します。

![Screen Shot 2015-12-09 at 23.36.50.png](https://qiita-image-store.s3.amazonaws.com/0/752/5ced3db2-5ea2-4646-3d60-f62a852c9503.png)
ストーレジ...

すると`Blank`の[_theme.less](https://github.com/magento/magento2/blob/develop/app/design/frontend/Magento/blank/web/css/source/_theme.less)に変わって新しい変数が組み込まれます。

<img width="652" alt="スクリーンショット 2015-12-09 23.35.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/752/80e423b2-a160-da0e-be0f-83489bc2da58.png">

__定義されたLESS変数__と__ディレクトリルール__を覚えてしまえばなんてことはないのですが、覚えるまでが大変というMagentoらしさは健在です。

### Tips. デバッグ
Magento2リリースちょっと前のDevDocsには、

`修正個所を見つける方法は、CSSのクラス名とモジュールの位置を把握して全ファイル検索すればOKじゃない？`

とかいうなかなかファンキーな内容があった気がするのですが、今はLESS.jsのconfigで元ファイル・ライン情報を出力する方針になっている模様です。

詳しくは[Styles debugging](http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/css-topics/css_debug.html)に記載されていますが、

[`lib/web/less/config.less.js`](https://github.com/magento/magento2/blob/develop/lib/web/less/config.less.js)

を編集して、`less.js`の[オプション](http://lesscss.org/usage/#using-less-in-the-browser)を有効にするとのことです。


## 備考：M2は非開発者にとってスタイル変更すらも難しい
ちょっとした感想ですが、Magento2はスタイル変更も↑こんな状態で、また別の設計や手順も含め、もはや職業開発者でない方が自分でやろうとしてやれるだろう範囲は、ずいぶん手前で超えてしまっています。たとえ挑戦してみようと決心されたとしても何から何までハードルが高めの心折設計です。もちろん、HTML書けたら職業開発者だった頃から考えれば、そうでない方の持てる技術というものは時代にあわせて変化しますし、野生のプロもいますし日本語情報も増えるはずですが、Magento2の諸々の設計やニュアンスを見る限り、

__Magento2を使う = 訓練された開発会社を呼ぶ__

という線を公式がきっちり引いた印象です。開発者個人としては月額3000円以下で独ドメECを提供するサービスがある中で、そんなんじゃ月のインフラ代金にもならない良くも悪くもハイスペックなMagento2という棲み分けには興味が尽きませんが、これに関してはまたゆっくりと考えていこうかと思います。

### 明日は、、
再び@macsetoさんお願いいたします！